Crlf Injection in Express (Javascript)
Crlf Injection in Express with Javascript — how this specific combination creates or exposes the vulnerability
Crlf Injection occurs when an attacker can insert a CRLF sequence (carriage return + line feed, represented as \r\n) into a header or the status line sent by the server. In Express with JavaScript, this typically arises when dynamic values from user input—such as query parameters, headers, or request bodies—are placed directly into HTTP response headers without validation or sanitization. Because HTTP headers are separated by \r\n, injecting this sequence allows an attacker to split the header block and inject additional headers or even a second status line, leading to HTTP response splitting, cache poisoning, or cross-site scripting via the injected headers.
Express itself does not automatically sanitize values used in functions like res.set(), res.header(), or when constructing redirects via res.location(). If a JavaScript string derived from req.query, req.headers, or any user-controlled source includes \r\n and is passed to these APIs, the server can be tricked into ending a header prematurely. For example, setting a header as res.set('X-Message', userValue) where userValue contains \r\nX-Injected: 1 results in two distinct headers after the split. This can enable attacks such as injecting a Location header to open a malicious redirect or smuggling requests through caching proxies. The risk is compounded when the response is later rendered in a browser or consumed by other systems that rely on the integrity of the header block.
Real-world attack patterns include using Crlf Injection to set arbitrary Cache-Control headers, poison CDN caches, or perform cross-site scripting when injected headers influence client-side behavior. Because the vulnerability exists at the protocol level, it can affect any HTTP server that reflects user input into headers. middleBrick’s scans include checks for unsafe header handling and reflected user input in response headers, which can surface these classes of issues during an unauthenticated black-box scan.
Javascript-Specific Remediation in Express — concrete code fixes
To prevent Crlf Injection in Express JavaScript applications, treat all user-controlled data as untrusted and ensure it cannot contain CR or LF characters before being used in headers. The safest approach is to avoid direct concatenation and instead use Express APIs defensively. Validate and sanitize inputs by removing or replacing \r and \n characters, and prefer built-in methods that do not allow header splitting.
Below are concrete code examples illustrating vulnerable patterns and their secure replacements.
Vulnerable pattern: direct use of user input in headers
// BAD: user-controlled value placed directly into a header
app.get('/echo', (req, res) => {
const userValue = req.query.text; // e.g., text=hello%0D%0AX-Injected:%201
res.set('X-Message', userValue);
res.send('ok');
});
Secure remediation: sanitize and validate input
// GOOD: remove CR and LF characters before using in headers
app.get('/echo', (req, res) => {
const userValue = (req.query.text || '').replace(/[\r\n]/g, '');
res.set('X-Message', userValue);
res.send('ok');
});
Alternative: use a whitelist or strict encoding for expected values
// GOOD: validate against an allowed pattern (e.g., alphanumeric and spaces)
app.get('/greet', (req, res) => {
const name = req.query.name;
if (!name || /[^a-zA-Z\s]/.test(name)) {
return res.status(400).send('Invalid name');
}
res.set('X-Greeting', `Hello, ${name}`);
res.send('ok');
});
For redirects, validate and avoid concatenating raw input into Location
// GOOD: validate and use a safe base URL
app.get('/redirect', (req, res) => {
const target = req.query.to;
const allowedHosts = ['example.com', 'app.example.com'];
try {
const url = new URL(target);
if (!allowedHosts.includes(url.hostname)) {
return res.status(400).send('Not allowed');
}
res.redirect(302, url.toString());
} catch (err) {
res.status(400).send('Invalid URL');
}
});
These patterns ensure that user input cannot introduce line breaks into headers. In addition to input sanitization, consider using a centralized middleware to normalize and validate headers across your application. middleBrick’s scans can detect endpoints where user input reaches response headers unsanitized, helping you identify and prioritize remediation.