HIGH crlf injectionrocketcockroachdb

Crlf Injection in Rocket with Cockroachdb

Crlf Injection in Rocket with Cockroachdb — how this specific combination creates or exposes the vulnerability

Crlf Injection occurs when an attacker can inject carriage return (CR, \r) and line feed (\n) characters into an HTTP response, causing the response to be split and additional headers or body content to be injected. In a Rocket application using Cockroachdb as the backend datastore, this risk arises when user-controlled input is reflected into HTTP headers or status lines without proper sanitization, and the database layer is used to retrieve or store that input. Rocket’s request guards and response building APIs allow direct control over headers and status, so if values from Cockroachdb queries are written into headers such as Location, Set-Cookie, or custom headers without validation, an attacker can inject newline sequences to manipulate the response structure.

Consider a Rocket route that fetches a redirect URL from Cockroachdb and uses it in a Redirect response:

#[get("/redirect")]
async fn redirect(client: &Client) -> Redirect {
    let url: String = client.query_one("SELECT url FROM redirects WHERE id = $1", &[&1])
        .await
        .unwrap()
        .get(0);
    Redirect::found(url)
}

If the url stored in Cockroachdb contains a sequence like https://example.com\r\nSet-Cookie: session=attacker, Rocket’s Redirect builder will embed that value into the HTTP response line and headers, causing the injected header to be interpreted by the client. This can lead to session fixation, cache poisoning, or open redirects. The same applies when query results are used in JSON responses that set custom headers elsewhere in the application, or when status messages are derived from database content.

Because Rocket applications often integrate Cockroachdb for strong consistency and global distribution, developers may inadvertently trust database values as safe for header use. The combination of Rocket’s ergonomic response builders and Cockroachdb’s SQL interface means that without input validation and output encoding specific to header contexts, Crlf Injection becomes a realistic threat vector. Security checks such as Input Validation and Property Authorization in middleBrick can detect these dangerous patterns by correlating data flows from the database to HTTP responses.

Cockroachdb-Specific Remediation in Rocket — concrete code fixes

Remediation focuses on ensuring that any data retrieved from Cockroachdb and used in HTTP responses is sanitized for header context. The primary rule is to never directly embed database strings into headers or status lines. Instead, validate and transform values so that CR and LF characters are either removed or percent-encoded as appropriate.

For the redirect example, validate the URL to ensure it does not contain newline characters and enforce a strict allowlist of domains or schemes:

use rocket::http::Status;
use rocket::response::Redirect;

async fn safe_redirect(client: &Client, id: i32) -> Result<Redirect, Status> {
    let row = client.query_one(
        "SELECT url FROM redirects WHERE id = $1",
        &[&id]
    ).await.map_err(|_| Status::NotFound)?;
    let url: String = row.get(0);
    if url.contains('\r') || url.contains('\n') {
        return Err(Status::BadRequest);
    }
    // Optionally enforce a domain allowlist
    if !url.starts_with("https://trusted.example.com/") {
        return Err(Status::Forbidden);
    }
    Ok(Redirect::found(url))
}

When constructing custom headers from Cockroachdb values, use Rocket’s header utilities to set headers safely, avoiding raw string concatenation that could embed newlines:

use rocket::http::Header;
use rocket::response::Response;

#[post("/set")]
async fn set_header(client: &Client, mut response: Response) -> &str {
    let row = client.query_one(
        "SELECT value FROM settings WHERE key = $1",
        &[&"cache_control"]
    ).await.unwrap();
    let value: String = row.get(0);
    // Sanitize: remove CR/LF before using as header value
    let sanitized = value.replace(|c| c == '\r' || c == '\n', "");
    response.set_header(Header::new("X-Custom-Value", sanitized));
    "ok"
}

For JSON APIs, ensure that any user-facing strings are serialized in a way that does not allow header injection when the JSON is later used in a header context. Use Rocket’s response guards and proper content-type handling to keep boundaries clear. middleBrick’s Input Validation checks can help identify endpoints where database-derived strings reach headers without sanitization.

Additionally, prefer parameterized queries and schema constraints in Cockroachdb to limit the content that can be stored. For example, enforce a URL schema check at the database level to reduce the risk of storing malicious payloads that could later be used in injection attacks:

ALTER TABLE redirects ADD CONSTRAINT valid_url CHECK (url ~ '^https?://[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}(/.*)?$');

Frequently Asked Questions

How can I test my Rocket + Cockroachdb endpoints for Crlf Injection using middleBrick?
Submit your API URL to middleBrick’s free scan; the Input Validation and Property Authorization checks will flag endpoints where database-derived values reach HTTP headers or status lines without sanitization.
Does middleBrick provide specific guidance for fixing Crlf Injection in Rocket applications?