Crlf Injection in Loopback with Cockroachdb
Crlf Injection in Loopback with Cockroachdb — how this specific combination creates or exposes the vulnerability
Crlf Injection occurs when user-controlled data is reflected into HTTP headers or query constructs without sanitization, enabling an attacker to inject carriage return (CR, \r) and line feed (\n) sequences. In a Loopback application that uses Cockroachdb as the backend, this risk is amplified when request parameters or headers are directly interpolated into SQL queries or when response headers are built from unchecked input.
Consider a Loopback endpoint that fetches user records by email via a raw query or an ORM-style where filter. If the email parameter is taken directly from the request and used to construct a query string, an attacker could supply [email protected]%0D%0AX-Header: injected. The CRLF sequence terminates the intended header line and starts a new one, potentially injecting headers such as Set-Cookie or manipulating the response structure. While Cockroachdb itself treats the injected payload as a literal string and does not parse CRLF, the surrounding Loopback and HTTP layer may act on the injected header lines, leading to HTTP response splitting, cache poisoning, or client-side manipulation.
Another vector involves logging or error handling. If an error message includes user input (e.g., a query parameter used in a raw SQL string) and that message is later written to a log file or returned in a debug header, CRLF injection can forge log entries or trigger log injection, complicating audit and monitoring. Cockroachdb error responses may include query fragments; if these are concatenated with unchecked input in the application layer, the resulting log line can be polluted with injected CRLF characters.
In Loopback, developers might use the db.models.query pattern or raw execute calls. If user input is interpolated via string concatenation or template literals without validation, the CRLF sequences become part of the data sent to Cockroachdb. Cockroachdb executes the query as intended, but the malicious payload resides in the parameter values, and the harm occurs downstream when those values are reflected elsewhere (e.g., in JSON responses or logs).
OpenAPI/Swagger specs that define parameters without strict schema constraints or with permissive pattern rules may inadvertently allow CRLF characters. When combined with Loopback’s dynamic model binding and Cockroachdb’s flexible string handling, the attack surface widens. The scanner checks for missing input sanitization and header reflection points, highlighting where user data reaches HTTP headers or query contexts in a Loopback+Cockroachdb stack.
Cockroachdb-Specific Remediation in Loopback — concrete code fixes
Remediation focuses on strict input validation, avoiding string interpolation for queries, and ensuring that user-controlled data never reaches header construction or logging without sanitization.
- Use parameterized queries or Loopback’s built-in query filters instead of raw SQL string concatenation. This prevents CRLF characters from being interpreted as control characters in the HTTP layer even if they exist in the data.
// Unsafe: string interpolation of user input const email = req.query.email; const sql = 'SELECT * FROM users WHERE email = \'${email}\';'; await db.execute(sql); // Safe: use parameterized queries or Loopback where filter const whereClause = { email: email }; const users = await db.models.User.find({ where: whereClause });
- Validate and sanitize all inputs that may be reflected in headers or logs. Reject or encode CR and LF characters for fields that are not expected to contain multi-line values.
// Validate email to disallow CRLF
const email = req.query.email;
if (typeof email !== 'string' || email.includes('\r') || email.includes('\n')) {
throw new Error('Invalid input: CRLF characters not allowed');
}
const whereClause = { email: email };
const users = await db.models.User.find({ where: whereClause });
- When constructing HTTP responses or logs, explicitly strip or encode CRLF characters to prevent response splitting or log injection.
function sanitizeHeaderValue(value) {
return value.replace(/[\r\n]/g, '');
}
const displayName = sanitizeHeaderValue(req.body.name);
// Use displayName in business logic; never directly in header assignment
- Leverage Loopback’s model validation hooks to enforce constraints at the framework level. Define strict JSON schema validation for model properties that interact with Cockroachdb.
// In user.model.json
{
"name": "User",
"properties": {
"email": {
"type": "string",
"required": true,
"pattern": "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$"
}
},
"validations": []
}
// In user.model.ts, add a custom validator to reject CRLF
User.observe('before save', function rejectCrlf(ctx, next) {
if (ctx.instance && (ctx.instance.email.includes('\r') || ctx.instance.email.includes('\n'))) {
ctx.reject('Email must not contain CR or LF characters');
}
next();
});
These practices ensure that user input remains data and does not become executable control information, mitigating Crlf Injection risks in a Loopback application using Cockroachdb.