Crlf Injection in Express with Cockroachdb
Crlf Injection in Express with Cockroachdb — 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) sequence into a header or query parameter, causing the application to split and inject additional headers or commands. In Express, this commonly arises when user-controlled input is reflected in HTTP response headers or when constructing SQL queries for Cockroachdb without proper sanitization. Cockroachdb uses a PostgreSQL-compatible wire protocol and SQL syntax, and while it does not treat newline characters as special in SQL values, an attacker can still exploit Crlf Injection at the HTTP layer before data reaches the database.
When Express applications dynamically set headers such as Location, Content-Type, or X-Response-ID using user input, a payload like example.com\r\nSet-Cookie: session=attacker can split the header and inject a new one. If the Express app builds a redirect using values from a Cockroachdb row (e.g., a stored redirect target or a user-controlled URL), the risk is realized. For example, an endpoint like /redirect?url_id=123 might fetch a target URL from Cockroachdb and respond with res.redirect(targetUrl). If targetUrl contains a CRLF sequence, the injected header can cause response splitting, potentially leading to cache poisoning, cross-site scripting in headers, or authentication bypass via injected cookies.
Even though Cockroachdb safely parameterizes SQL queries, the vulnerability is not in the database driver but in how the application uses retrieved data in HTTP constructs. An attacker might first store a malicious payload in Cockroachdb (e.g., via a compromised admin UI or an insecure import), and then trigger its use in Express response headers. Because Cockroachdb returns plain strings, the injected CRLF sequences are preserved and passed to Express, enabling header manipulation. This is especially relevant when using features like LISTEN/NOTIFY or changefeeds where application logic consumes database events and builds HTTP responses dynamically.
Common OWASP API Top 10 risks related to this pattern include API1:2023 – Broken Object Level Authorization when injected headers elevate privileges, and API5:2023 – Broken Function Level Authorization if an injected header triggers unwanted internal routing. Input validation and output encoding must be applied to any data sourced from Cockroachdb before it is used in headers, URLs, or other HTTP control structures. MiddleBrick’s LLM/AI Security checks and 12 parallel scans can detect response splitting and header injection patterns, providing prioritized findings and remediation guidance to prevent Crlf Injection in this specific stack.
Cockroachdb-Specific Remediation in Express — concrete code fixes
To prevent Crlf Injection in Express applications that use Cockroachdb, treat all data originating from the database as untrusted when it flows into HTTP headers or redirects. The most effective remediation is strict input validation and output encoding combined with safe usage of Express APIs. Below are concrete code examples demonstrating secure patterns.
1. Safe redirect construction with validation
Instead of directly using a Cockroachdb value in res.redirect(), validate and normalize the target URL. Use a whitelist of allowed domains or path prefixes and reject any URL containing CRLF characters.
const express = require('express');
const { Pool } = require('pg'); // Cockroachdb compatible driver
const app = express();
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
function isValidRedirectUrl(url) {
try {
const parsed = new URL(url, 'https://base.example.com');
// Allow only specific safe prefixes
if (!parsed.pathname.startsWith('/safe/')) return false;
// Reject if CRLF present (defense in depth)
if (/[\r\n]/.test(url)) return false;
return true;
} catch (err) {
return false;
}
}
app.get('/redirect', async (req, res) => {
const { id } = req.query;
const client = await pool.connect();
try {
const result = await client.query('SELECT target_url FROM redirect_rules WHERE id = $1', [id]);
if (result.rows.length === 0) return res.status(404).send('Not found');
const targetUrl = result.rows[0].target_url;
if (!isValidRedirectUrl(targetUrl)) {
return res.status(400).send('Invalid redirect target');
}
res.redirect(302, targetUrl);
} finally {
client.release();
}
});
2. Sanitizing header values from Cockroachdb
If you must set headers derived from database values, strip or encode CRLF characters and avoid passing raw strings to header-setting functions.
function safeHeaderValue(value) {
return value.replace(/[\r\n]+/g, '');
}
app.get('/profile', async (req, res) => {
const { userId } = req.params;
const client = await pool.connect();
try {
const result = await client.query('SELECT display_name FROM users WHERE id = $1', [userId]);
if (result.rows.length === 0) return res.status(404).send('Not found');
const displayName = safeHeaderValue(result.rows[0].display_name);
res.set('X-Display-Name', displayName);
res.json({ display_name: displayName });
} finally {
client.release();
}
});
3. Using parameterized queries and avoiding concatenation
Always use parameterized queries with Cockroachdb to prevent SQL injection, which can indirectly reduce opportunities for stored CRLF payloads. Never concatenate user input into SQL strings.
// Safe parameterized query
const result = await pool.query(
'INSERT INTO audit_log(event, user_id) VALUES($1, $2) RETURNING id',
[event, userId]
);
By combining these practices—validating and encoding data from Cockroachdb, avoiding direct use of database values in HTTP headers, and using parameterized queries—you can effectively mitigate Crlf Injection risks in Express applications.