Crlf Injection in Sails with Hmac Signatures
Crlf Injection in Sails with Hmac Signatures — how this specific combination creates or exposes the vulnerability
Crlf Injection occurs when an attacker can inject a carriage return (CR, \r) and line feed (\n) into a header or cookie value, causing the application to prematurely terminate the current header line and inject additional headers or responses. In Sails.js, this risk can intersect with Hmac Signatures when the framework uses signed or hashed identifiers (e.g., in cookies, query parameters, or custom headers) to validate requests. If an attacker can control part of the data that is included in the value that is signed, and that value is later reflected into a header or cookie without proper sanitization, they may be able to inject newline characters that alter the parsing of the signed payload or the surrounding protocol stream.
Consider a scenario where Sails uses a signed token in a cookie to maintain anti-CSRF or session integrity. If the token is constructed by concatenating user-influenced data (such as a user ID or a chosen language preference) with a server-side secret and then that token is placed into a Set-Cookie header, unsanitized newline characters in the user-controlled portion can break header structure. For example, a newline injected into a cookie value can cause the client or intermediary to interpret subsequent content as a new header, potentially smuggling requests or bypassing intended scope validation. The Hmac Signature itself may remain valid if the injection occurs outside the signed portion; however, the surrounding protocol semantics can be subverted, leading to response splitting, session fixation, or bypass of same-site cookie handling logic.
In Sails, this often surfaces in actions that dynamically build headers or cookies using data from request parameters without strict validation or encoding. Because Hmac Signatures are commonly used to ensure integrity of tokens or identifiers, developers may mistakenly assume that signature verification alone protects against injection. In practice, signature checks confirm that the token has not been altered, but they do not sanitize the token’s contents before it is used in a header context. If the token includes newline characters and is later written into a Set-Cookie or similar header, the injection is still possible because the signature does not enforce header-safe formatting. This creates a pathway where an attacker can manipulate the structure of the HTTP message stream despite the presence of cryptographic integrity checks.
Hmac Signatures-Specific Remediation in Sails — concrete code fixes
To mitigate Crlf Injection risks when using Hmac Signatures in Sails, ensure that any data incorporated into signed values or subsequently rendered into headers is strictly sanitized and encoded. Never directly embed user-controlled strings into header values, including cookie values, even if they are covered by an Hmac Signature. Instead, validate character sets, disallow control characters such as \r and \n, and use canonical encoding before placing data into headers.
Below is a concrete Sails example that demonstrates a vulnerable pattern and a remediated version. The vulnerable code signs a user-supplied string and sets it in a cookie without sanitization:
// Vulnerable: userInput may contain newline characters
const userInput = req.param('data');
const payload = userInput + '.' + crypto.createHmac('sha256', secret).update(userInput).digest('hex');
res.cookie('signedData', payload);
In this example, if userInput contains \r\n sequences, they can break the cookie header. The remediated version validates and sanitizes the input before constructing the signed value and setting the cookie:
// Secured: strip or reject newline characters
const userInput = req.param('data');
if (/[\r\n]/.test(userInput)) {
return res.badRequest('Invalid input: newlines not allowed');
}
const hmac = crypto.createHmac('sha256', secret);
const signature = hmac.update(userInput).digest('hex');
const payload = `${userInput}.${signature}`;
// Safe: userInput has been validated, and cookie value is controlled
res.cookie('signedData', payload, { httpOnly: true, sameSite: 'strict' });
Additionally, when using Hmac Signatures for API authentication headers, apply the same discipline: reject or encode newline-containing values before including them in the Authorization header or any custom header. For cookie-based sessions, consider using frameworks that enforce HttpOnly, Secure, and SameSite attributes, and ensure that the signed payload does not rely on embedding raw user input into header-sensitive contexts. These steps reduce the attack surface for Crlf Injection while preserving the integrity guarantees provided by Hmac Signatures.