HIGH crlf injectionsailshmac signatures

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.

Frequently Asked Questions

Can a valid Hmac Signature prevent Crlf Injection if the data is user-controlled?
No. A valid Hmac Signature confirms integrity but does not sanitize content. If newline characters are present in user-controlled data and that data is later placed into headers or cookies, injection can still occur because signature checks do not enforce header-safe formatting.
What specific validation should be applied before using data in Set-Cookie in Sails?
Reject or encode CR (\r) and LF (\n) characters, enforce a strict allowed character set (e.g., alphanumerics and a limited safe subset), and avoid embedding raw user input directly into cookie values; always use HttpOnly, Secure, and SameSite attributes where appropriate.