Crlf Injection in Koa with Hmac Signatures
Crlf Injection in Koa with Hmac Signatures — how this specific combination creates or exposes the vulnerability
Crlf Injection occurs when an attacker can inject CRLF sequences (\r\n) into a header or value that is later reflected in HTTP messages. In Koa, this commonly arises when dynamic values—such as a user-controlled redirect target, a locale, or a token—are written into response headers without validation or sanitization. If the application also uses Hmac Signatures to ensure integrity of requests or tokens, the combination can amplify risks in two ways.
First, an attacker may inject a newline to create two separate header blocks, smuggling a crafted header past a gateway or proxy that only validates the first line. If the Hmac is computed over a subset of headers or parameters and then forwarded or logged without including the smuggled header, the server may process the request as intended while an intermediary sees a different set of authenticated data. This mismatch can bypass intended integrity checks because the Hmac does not cover the injected header, allowing an attacker to modify or replay parts of the request under a valid signature context.
Second, consider a Koa endpoint that accepts an id_token or a signed callback URL. If the application appends user input directly into a Location or Set-Cookie header and then recomputes an Hmac over the outgoing payload, the injected \r\n can cause the client to parse additional headers or cookies. From a security testing perspective, this behavior can be discovered during the Header Smuggling and Input Validation checks that middleBrick runs in parallel. middleBrick flags such outcomes as high-severity findings because an attacker can use CRLF to forge secondary headers that appear under the Hmac umbrella without the server explicitly endorsing them.
In practice, this means the server’s cryptographic integrity mechanism (Hmac Signatures) does not protect against structural message manipulation at the protocol level. The vulnerability is not in the Hmac algorithm itself, but in how user input is handled before the signature is applied and how the resulting message is assembled. middleBrick’s OpenAPI/Swagger analysis helps surface endpoints where user-controlled fields are mapped to headers, enabling you to identify where CRLF injection could coexist with Hmac-based integrity checks.
Hmac Signatures-Specific Remediation in Koa — concrete code fixes
Remediation focuses on input validation, canonicalization, and ensuring the Hmac covers the full set of data that will be transmitted. Below are concrete Koa patterns that prevent CRLF injection while preserving Hmac integrity.
1. Reject or encode newline characters in header inputs
Never pass raw user input into header values. Validate and sanitize before use:
const sanitizeHeaderValue = (value) => {
if (typeof value !== 'string') return value;
if (/[\r\n]/.test(value)) {
throw new Error('Invalid header value: newline characters not allowed');
}
return value;
};
// Usage in a Koa controller
ctx.assert(headers['x-correlation-id'], 400, 'Missing correlation id');
const correlationId = sanitizeHeaderValue(headers['x-correlation-id']);
ctx.set('X-Correlation-Id', correlationId);
2. Use a canonical representation before Hmac computation
Compute the Hmac over a canonical string that excludes any mutable or user-controlled header fields that could be injected. This ensures the signature cannot be bypassed by smuggling headers.
const crypto = require('crypto');
const computeHmac = (method, path, canonicalBody, timestamp, secret) => {
const payload = [
method.toUpperCase(),
path,
canonicalBody,
timestamp,
].join('\n');
return crypto.createHmac('sha256', secret).update(payload).digest('hex');
};
// In a Koa middleware
const timestamp = Date.now().toString();
const body = ctx.request.rawBody; // or a canonical JSON string
const signature = computeHmac(ctx.method, ctx.path, body, timestamp, process.env.HMAC_SECRET);
ctx.set('X-Request-Timestamp', timestamp);
ctx.set('X-Request-Signature', signature);
3. Validate and constrain dynamic redirects
If your Koa app issues redirects based on user input, ensure the target is restricted to trusted origins and does not contain newline characters:
const trustedHosts = new Set(['app.example.com', 'api.example.com']);
const isValidRedirect = (url) => {
try {
const u = new URL(url, 'https://placeholder.com');
return trustedHosts.has(u.hostname) && !u.searchParams.has('callback') && !/[\r\n]/.test(u.href);
} catch {
return false;
}
};
ctx.assert(isValidRedirect(redirectUrl), 400, 'Invalid redirect target');
ctx.redirect(redirectUrl);
4. Ensure Hmac covers all signed headers
If you sign a subset of headers, explicitly include them in the Hmac input and reject requests that contain additional headers not covered. This prevents header smuggling:
const signedHeaders = ['x-request-timestamp', 'x-request-scope'];
const verifyHmac = (req, secret) => {
const received = req.get('X-Request-Signature');
const timestamp = req.get('X-Request-Timestamp');
const scope = req.get('X-Request-Scope');
if (!received || !timestamp || !scope) return false;
const payload = signedHeaders.map(h => `${h}:${req.get(h)}`).join('\n');
const expected = crypto.createHmac('sha256', secret).update(payload).digest('hex');
return crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
};
// In Koa context
ctx.assert(verifyHmac(ctx, process.env.HMAC_SECRET), 401, 'Invalid signature');
5. Use framework-level security middleware
Leverage Koa utilities to set headers safely and avoid concatenation patterns that invite injection:
const Router = require('@koa/router');
const router = new Router();
router.get('/profile', (ctx) => {
// Safe: using ctx.set with a validated string
const safeValue = encodeURIComponent(user.locale).replace(/%5C/g, '');
ctx.set('X-Locale', safeValue);
ctx.body = { locale: user.locale };
});
These practices ensure that Hmac Signatures remain a robust integrity mechanism while mitigating CRLF injection risks. By combining strict input validation, canonical Hmac computation, and careful header management, you reduce the attack surface exposed through header smuggling in Koa applications.