Request Smuggling in Feathersjs with Hmac Signatures
Request Smuggling in Feathersjs with Hmac Signatures — how this specific combination creates or exposes the vulnerability
Request smuggling occurs when an application processes HTTP requests differently in transit versus at the backend, allowing attackers to smuggle requests across security boundaries. In FeathersJS applications that use Hmac Signatures for request authentication, this risk emerges when the API gateway or load balancer parses and forwards requests differently than the FeathersJS service does.
Consider a setup where a gateway terminates TLS, normalizes headers, and forwards requests to FeathersJS. If the gateway uses one header set for Hmac verification (for example, using the original x-forwarded-* headers) while FeathersJS computes the Hmac over the raw or differently ordered headers, the two interpretations of the request can diverge. An attacker can craft a request with an Transfer-Encoding: chunked header and a Content-Length header. A vulnerable front-end may process the request using one message boundary (e.g., chunked) while the FeathersJS backend parses it using another (e.g., content length), effectively smuggling a second request through that is not covered by the Hmac signature context.
With Hmac Signatures in FeathersJS, the signature is typically computed over selected headers and the body. If the signature scope is inconsistent between the gateway and the service, a smuggled request may reach internal routes without a valid Hmac context, bypassing intended authentication and authorization. For example, an endpoint intended to be read-only might be invoked with a secondary request that performs a write, because the gateway allowed smuggling and the FeathersJS service accepted it based on a mismatched signature scope. This becomes especially dangerous when the gateway performs operations like header folding or when different servers in the chain interpret header case-sensitivity differently, leading to request splitting or response splitting attacks.
Real-world impact includes unauthorized data access or modification, privilege escalation, and potential SSRF if internal endpoints are exposed via smuggling. Because FeathersJS often integrates with transports like REST and WebSocket, inconsistent header handling across protocol boundaries can exacerbate the issue. The vulnerability is not in Hmac itself, but in how the request’s surface is defined for signing and verification across the stack.
Hmac Signatures-Specific Remediation in Feathersjs — concrete code fixes
Remediation focuses on ensuring a single, canonical interpretation of the request across all layers and that the Hmac signature scope is consistent and strict.
1. Canonicalization and strict header handling
Normalize headers before signing and verification. Use lowercase header names and enforce a consistent order. Do not rely on front-end or proxy headers for signature computation unless they are explicitly trusted and validated.
// utils/signing.js
const crypto = require('node:crypto');
function buildCanonicalString(headers, body) {
// Normalize: sort lowercased header names, exclude hop-by-hop headers
const hopByHop = new Set(['keep-alive', 'proxy-authenticate', 'proxy-authorization',
'te', 'trailers', 'transfer-encoding', 'upgrade', 'connection', 'content-length', 'host']);
const keys = Object.keys(headers)
.map(k => k.toLowerCase())
.filter(k => !hopByHop.has(k))
.sort();
const headerString = keys.map(k => `${k}:${headers[k]}`).join('\n');
return `POST\n/api/v1/resource\n${headerString}\n\n${body}`;
}
function createHmacSignature(secret, headers, body) {
const canonical = buildCanonicalString(headers, body);
return crypto.createHmac('sha256', secret).update(canonical).digest('hex');
}
module.exports = { createHmacSignature, buildCanonicalString };
2. Consistent signature scope on server and gateway
Ensure both gateway and FeathersJS use the same set of headers and body representation. Avoid relying on x-forwarded-* for signature computation unless those values are validated and mapped correctly.
// services/authentication.js
const { createHmacSignature } = require('../utils/signing');
module.exports = function hmacAuthentication(secret) {
return async context => {
const { headers, body } = context.params.http;
const provided = headers['x-api-signature'];
const expected = createHmacSignature(secret, headers, JSON.stringify(body));
if (!provided || provided !== expected) {
throw new Error('Invalid signature');
}
return context;
};
};
Apply this hook as a before hook in your FeathersJS service to reject requests with mismatched signatures early.
3. Disable ambiguous front-end parsing and enforce strict transport handling
Configure your gateway to not perform header transformations that change the effective request between gateway and service. Disable header folding and ensure Transfer-Encoding and Content-Length are not both present. If you must accept chunked encoding, normalize it before forwarding and compute the Hmac over the normalized body.
// Example: ensure a single content-length and reject ambiguous encodings
const enforceSingleContentLength = (req, res, next) => {
const hasTE = req.headers['transfer-encoding'] && req.headers['transfer-encoding'].toLowerCase() === 'chunked';
const hasCL = req.headers['content-length'];
if (hasTE && hasCL) {
return res.status(400).send('Ambiguous message framing');
}
next();
};
4. MiddleBrick alignment
When scanning FeathersJS APIs with Hmac Signatures, middleBrick’s OpenAPI/Swagger analysis resolves $ref definitions and cross-references runtime behavior, helping identify mismatches in signature scope or header handling. The scanner’s 12 security checks run in parallel and include Authentication and BOLA/IDOR assessments tailored to Hmac-protected endpoints. If you want continuous visibility, the Pro plan provides continuous monitoring so changes to header handling or spec definitions trigger alerts before smuggling risks reach production.