Header Injection in Express with Bearer Tokens
Header Injection in Express with Bearer Tokens — how this specific combination creates or exposes the vulnerability
Header Injection in Express when Bearer Tokens are used happens when untrusted input from requests is placed into HTTP headers without validation or escaping. If an application builds headers using string concatenation or interpolation with user-controlled data, an attacker can inject additional headers or override security-critical ones. Common patterns vulnerable to injection include setting authorization-related headers such as Authorization or forwarding values into x-forwarded-* headers.
In the context of Bearer Tokens, injection often targets the Authorization header format Bearer <token>. If an Express app concatenates a user-supplied value into that header, an attacker can supply a token string containing a newline and additional header lines (e.g., abc\r\nX-Admin: true). Depending on downstream components (reverse proxies, frameworks, or libraries), these injected lines may be interpreted as separate headers, enabling privilege escalation, request smuggling, or cache poisoning. Even when using Bearer tokens for authentication, injection in other headers (such as Host or custom headers) can affect routing, logging, or middleware behavior, changing how the request is processed before it reaches token validation logic.
Express itself does not inherently sanitize or validate header values; responsibility falls on the developer to treat all incoming data as untrusted. Attackers may also probe unauthenticated endpoints to discover whether header injection is possible before authentication is enforced. Because Bearer tokens are often validated after headers are parsed, injected headers can alter control flow or bypass intended security boundaries. This is especially risky when combined with middleware that relies on headers for routing, rate limiting, or tenant identification, as injected values may cause the application to misroute or misbehave.
For full API security assessment, scanning tools can detect whether endpoints reflect or misuse user input in headers and whether Bearer token handling occurs in a way that is resilient to injection. These scanners perform black-box testing against the unauthenticated attack surface, identifying risky patterns without requiring credentials.
Bearer Tokens-Specific Remediation in Express — concrete code fixes
To prevent Header Injection with Bearer Tokens in Express, avoid constructing header values using unsanitized input. Instead, validate and normalize all inputs and use language-safe APIs for header manipulation. Below are concrete, safe patterns and examples.
1. Validate and sanitize inputs before using them
Never directly interpolate user input into header values. Use strict allowlists and normalization for any data that influences headers or tokens.
// Unsafe: directly concatenating user input into Authorization
const userToken = req.query.token; // DO NOT DO THIS
res.set('WWW-Authenticate', 'Bearer ' + userToken);
// Safer: validate token format and avoid header construction from raw input
const userToken = req.query.token;
const tokenPattern = /^[A-Za-z0-9\-_=]+\.[A-Za-z0-9\-_=]+(\.[A-Za-z0-9\-_=]+)?$/; // JWT-like shape
if (typeof userToken === 'string' && tokenPattern.test(userToken)) {
// Use the token only for auth checks, not for reconstructing headers
if (isValidBearerToken(userToken)) {
req.authenticatedToken = userToken;
// proceed with business logic
} else {
res.status(401).send('Invalid token');
}
} else {
res.status(400).send('Malformed token');
}
2. Use framework-safe header setters and avoid newline characters
Express res.set() and res.header() can still be abused if values contain carriage returns or line feeds. Explicitly reject or strip newlines and use safe assignment patterns.
// Ensure header values cannot inject additional headers
const safeSetHeader = (res, name, value) => {
if (typeof value !== 'string') return;
const sanitized = value.replace(/\r?\n|\r/g, ''); // reject newlines
res.set(name, sanitized);
};
// Example usage with Authorization-related custom headers
const incoming = req.get('x-custom-token');
safeSetHeader(res, 'X-Custom-Token', incoming);
// Do not set Authorization from untrusted input
// Instead, rely on your authentication middleware to validate the Bearer token
app.use((req, res, next) => {
const auth = req.get('Authorization') || '';
const token = auth.startsWith('Bearer ') ? auth.slice(7) : '';
if (!token || !tokenPattern.test(token)) {
return res.status(401).send('Missing or invalid Bearer token');
}
req.authToken = token;
next();
});
3. Separate authentication from header manipulation and enforce strict content security
Keep token validation independent from header setting. Do not echo user input into security-sensitive headers such as Authorization, Host, or routing headers like x-forwarded-host. Use environment-trusted configuration for endpoints and proxies instead of request-derived values.
// Do not forward raw user input to downstream services or headers
const forwardedHost = req.get('x-forwarded-host');
if (forwardedHost) {
// Validate against allowed hosts or reject
const allowedHosts = new Set(['api.example.com', 'app.example.com']);
if (!allowedHosts.has(forwardedHost)) {
return res.status(400).send('Invalid forwarded host');
}
// Only then set if safe
safeSetHeader(res, 'X-Forwarded-Host', forwardedHost);
}
// Use standard authentication middleware for Bearer tokens
const jwt = require('jsonwebtoken');
app.use((req, res, next) => {
const auth = req.get('Authorization') || '';
const parts = auth.split(' ');
if (parts.length !== 2 || parts[0] !== 'Bearer') {
return res.status(401).send('Authorization header required');
}
try {
const decoded = jwt.verify(parts[1], process.env.JWT_PUBLIC_KEY);
req.user = decoded;
next();
} catch (err) {
return res.status(401).send('Invalid token');
}
});
These practices reduce the risk of header injection and ensure Bearer token handling remains predictable. Complement these code-level controls with automated scanning that checks for header manipulation risks and maps findings to frameworks such as OWASP API Top 10 and relevant compliance requirements.