Crlf Injection in Loopback with Bearer Tokens
Crlf Injection in Loopback with Bearer Tokens — how this specific combination creates or exposes the vulnerability
Crlf Injection occurs when user-controlled data is reflected into HTTP headers without sanitization, allowing an attacker to inject newline characters (CRLF = Carriage Return + Line Feed). In Loopback applications that use Bearer Tokens—typically passed via the Authorization header—this combination becomes dangerous when the framework or custom code copies an incoming header value into another response header without validation. For example, if an API endpoint echoes a token or a token-derived identifier into a non-security header such as X-Request-ID or X-Correlation-Id, a crafted token containing %0D%0A (or literal \r\n in some transports) can break header parsing and inject additional headers or response lines.
Consider a Loopback middleware that logs authorization context by forwarding the Bearer Token into a custom header:
app.middleware((ctx, next) => {
const auth = ctx.request.header.authorization; // Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
if (auth && auth.startsWith('Bearer ')) {
ctx.response.set('X-Token-Scheme', auth); // Dangerous: direct reflection
}
return next();
});
An attacker can supply Authorization: Bearer abc\r\nX-Admin: true, causing the server to emit two headers: X-Token-Scheme containing the token and a separate X-Admin header with value true. In a back-end integration where the token is later used to enforce authorization (e.g., scoping data access via an embedded sub), this injection can bypass intended security boundaries or facilitate response splitting. In Loopback, if the token is also parsed by custom logic that splits on whitespace or pipes results into downstream HTTP calls (SSRF), the injected headers may alter routing or headers in those calls.
Even when the Bearer Token is validated against an identity provider, the risk persists if the application reflects the token or its metadata into headers or cookies. For instance, returning the token inside Set-Cookie without proper escaping can lead to header injection that may assist in session fixation or client-side extraction. The vulnerability is not in the Bearer Token specification itself, but in how Loopback components handle and forward token-derived values into mutable header contexts.
Because middleBrick tests unauthenticated attack surfaces, it can detect header injection points where Bearer Tokens are reflected, even when authentication is otherwise required. Findings include evidence of response splitting and guidance to ensure token values are not directly embedded into headers.
Bearer Tokens-Specific Remediation in Loopback — concrete code fixes
Remediation focuses on two principles: never reflect raw Authorization header values into other headers, and treat Bearer Tokens as opaque strings that must not be parsed or forwarded without strict validation. Below are concrete Loopback examples that eliminate injection by sanitizing and isolating token handling.
1) Avoid reflecting Bearer Tokens into response headers
Instead of forwarding the Authorization header, extract only the scheme and a safe identifier (e.g., user ID) that has been verified server-side:
app.middleware((ctx, next) => {
const auth = ctx.request.header.authorization; // Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
if (auth && auth.startsWith('Bearer ')) {
const token = auth.substring(7); // Remove 'Bearer '
// Verify token via JWT verification or introspection; obtain verified claims
const claims = verifyToken(token); // returns { sub, scope, ... }
// Use verified, non-token data for headers
ctx.response.set('X-User-Id', claims.sub);
}
return next();
});
This ensures no attacker-controlled newline characters can reach response headers. The token itself remains in the request context but is not echoed back.
2) Sanitize any token-derived identifiers before header assignment
If you must include a token-related value in a header, strip or encode CRLF sequences explicitly:
function safeHeaderValue(value) {
return value.replace(/[\r\n]+/g, '');
}
app.middleware((ctx, next) => {
const auth = ctx.request.header.authorization;
if (auth && auth.startsWith('Bearer ')) {
const token = auth.substring(7);
const safe = safeHeaderValue(token);
ctx.response.set('X-Token-Hash', safe); // safe, but prefer not to set at all
}
return next();
});
Better yet, do not set such headers unless strictly necessary. For logging or correlation, generate a server-side UUID rather than reusing the token.
3) Secure cookie handling when tokens are stored client-side
If your Loopback app sets cookies based on token claims, always use httpOnly, secure, and same-site attributes, and avoid injecting raw token strings into cookie values:
ctx.cookies.set('session', verifiedSessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict',
path: '/'
});
By decoupling token verification from header/cookie reflection and relying on server-side claims, you mitigate Crlf Injection risks specific to Bearer Tokens in Loopback. middleBrick’s scans validate that such dangerous reflections are absent and provide prioritized remediation steps aligned with OWASP API Top 10 and compliance mappings.