Header Injection on Aws
How Header Injection Manifests in Aws
Header injection vulnerabilities in Aws applications typically arise when user input is incorporated into HTTP response headers without proper validation. In Aws Lambda functions and API Gateway implementations, this often occurs when developers construct custom headers based on request parameters, query strings, or body content.
A common Aws-specific pattern involves using request headers to dynamically set CORS headers or custom authentication tokens. For example, a Lambda function might extract the Origin header from a request and reflect it back in the Access-Control-Allow-Origin header:
exports.handler = async (event) => {
const origin = event.headers.origin || '*';
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': origin,
'Content-Type': 'application/json'
},
body: JSON.stringify({ message: 'Hello World' })
};
};This Aws pattern is vulnerable because an attacker can send a request with a malicious Origin header containing newline characters, allowing them to inject additional headers:
GET /api/resource HTTP/1.1
Host: example.com
Origin: http://evil.com%0d%0aX-Custom-Header: malicious-valueWhen the Lambda function reflects this Origin header, the response becomes:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://evil.com
X-Custom-Header: malicious-value
Content-Type: application/jsonThis Aws-specific vulnerability can lead to HTTP response splitting, XSS via injected headers, or cache poisoning when intermediaries process the malicious headers.
Another Aws-specific manifestation occurs in API Gateway authorizers that construct authorization headers. When using custom Lambda authorizers, developers might extract claims from tokens and construct response headers:
const generatePolicy = (principalId, effect, resource, claims) => {
const authResponse = {};
authResponse.principalId = principalId;
if (effect && resource) {
const policyDocument = {
Version: '2012-10-17',
Statement: [
{
Action: 'execute-api:Invoke',
Effect: effect,
Resource: resource
}
]
};
authResponse.policyDocument = policyDocument;
}
// Vulnerable: reflecting claims without validation
authResponse.context = claims;
return authResponse;
};If claims contain malicious header data, this can result in header injection when API Gateway processes the authorizer response.
Aws-Specific Detection
Detecting header injection in Aws environments requires understanding the specific Aws runtime and API Gateway behavior. When scanning Aws Lambda functions, look for patterns where request data flows into response headers without validation.
Using middleBrick's Aws-specific scanning capabilities, you can identify header injection vulnerabilities through automated testing. The scanner tests for newline character injection (%0d%0a, %0a%0d) in various request locations:
GET /api/resource HTTP/1.1
Host: example.com
X-Inject: innocent%0d%0aX-Malicious: injected-value
POST /api/resource HTTP/1.1
Host: example.com
Content-Type: application/json
{"header": "test%0d%0aBad-Header: evil"}middleBrick analyzes the actual HTTP responses returned by your Aws endpoints, detecting when injected headers appear in the response. This black-box approach works regardless of your implementation details, testing the unauthenticated attack surface that header injection vulnerabilities expose.
For Aws API Gateway specifically, header injection can occur in multiple locations:
- Integration request/response mapping templates
- API Gateway stage variables reflected in headers
- CORS configuration using request headers
- Custom authorizer responses
- Lambda function URLs with reflected headers
middleBrick's scanning engine tests each of these Aws-specific integration points, providing a comprehensive security assessment across your entire Aws API surface.
The scanner also checks for Aws-specific header injection patterns, such as:
- CloudFront headers being reflected without validation
- API Gateway custom domain headers
- AWS_REGION or AWS_ACCOUNT_ID headers being dynamically set
- Authorization headers constructed from JWT claims
Each finding includes the specific Aws service, endpoint, and vulnerability details, allowing you to quickly identify and remediate header injection issues in your Aws infrastructure.
Aws-Specific Remediation
Remediating header injection in Aws requires implementing strict validation and sanitization of all header values. For Aws Lambda functions, always validate and sanitize header values before including them in responses:
const sanitizeHeader = (value) => {
if (typeof value !== 'string') return '';
return value
.replace(/
/g, '')
.replace(/
/g, '')
.replace(/ /g, '')
.replace(/[ --]/g, '');
};
exports.handler = async (event) => {
const origin = sanitizeHeader(event.headers.origin || '*');
// Validate origin against allowed list
const allowedOrigins = ['https://example.com', 'https://app.example.com'];
const corsOrigin = allowedOrigins.includes(origin) ? origin : allowedOrigins[0];
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': corsOrigin,
'Content-Type': 'application/json'
},
body: JSON.stringify({ message: 'Hello World' })
};
};For Aws API Gateway, implement validation at the API Gateway level using request validation or VTL mapping templates:
#set($inputRoot = $input.path('$'))
{
#if($inputRoot.path("body"))
"body" : {
#foreach($key in $inputRoot.path("body").keySet())
#if($key.matches("(?i)(origin|referer|x-)") || $inputRoot.path("body").$key.contains("
") || $inputRoot.path("body").$key.contains("
"))
#set($skip = true)
#else
"$key" : "$util.escapeJavaScript($inputRoot.path("body").$key)",
#end
#end
}
#end
}When using Aws Lambda authorizers, validate claims before constructing response headers:
const validateClaims = (claims) => {
const sanitized = {};
for (const [key, value] of Object.entries(claims)) {
if (typeof value !== 'string') continue;
const sanitizedValue = value
.replace(/
/g, '')
.replace(/
/g, '')
.substring(0, 1000); // length limit
sanitized[key] = sanitizedValue;
}
return sanitized;
};
const generatePolicy = (principalId, effect, resource, claims) => {
const authResponse = {};
authResponse.principalId = principalId;
if (effect && resource) {
authResponse.policyDocument = {
Version: '2012-10-17',
Statement: [{
Action: 'execute-api:Invoke',
Effect: effect,
Resource: resource
}]
};
}
authResponse.context = validateClaims(claims);
return authResponse;
};For Aws API Gateway REST APIs, use the built-in validation features to prevent header injection at the infrastructure level:
- Enable request validation to reject requests with invalid headers
- Use VTL mapping templates to sanitize header values
- Configure CORS properly with static allowed origins rather than reflecting request headers
- Set up API Gateway stage variables with validation
For Aws AppSync GraphQL APIs, validate header-based authorization by implementing resolver-level validation:
const validateAuthorizationHeader = (headers) => {
const authHeader = headers['Authorization'];
if (!authHeader || typeof authHeader !== 'string') {
throw new Error('Missing or invalid Authorization header');
}
// Validate format and sanitize
const parts = authHeader.split(' ');
if (parts.length !== 2 || parts[0] !== 'Bearer') {
throw new Error('Invalid Authorization header format');
}
return parts[1]; // return token
};By implementing these Aws-specific remediation patterns, you can effectively prevent header injection vulnerabilities across your entire Aws API infrastructure.