HIGH header injectionexpressbearer tokens

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.

Frequently Asked Questions

Can header injection bypass Bearer token validation in Express?
Yes, if an attacker can inject a newline and additional headers before token validation middleware, they may alter the request interpretation. Prevent this by validating and normalizing all inputs and never constructing headers from untrusted data; validate Bearer tokens using strict parsing and library-supported verification rather than relying on reconstructed headers.
Does scanning detect header injection risks with Bearer tokens?
Yes, automated scans can identify endpoints that reflect or misuse user input in headers and highlight risky header construction patterns. Use a scanner that tests unauthenticated attack surfaces and provides prioritized findings with remediation guidance mapped to frameworks such as OWASP API Top 10.