HIGH crlf injectionrocketmutual tls

Crlf Injection in Rocket with Mutual Tls

Crlf Injection in Rocket with Mutual Tls

Crlf Injection occurs when an attacker can inject carriage return (CR, \r) and line feed (\n) sequences into HTTP headers, causing header splitting and potentially allowing response splitting or header injection. In Rocket, a Rust web framework, this typically arises when user-controlled input is reflected into headers such as Location, Content-Type, or custom headers without proper validation. When Mutual Tls (mTLS) is enforced, the server requests and validates a client certificate during the TLS handshake. While mTLS strengthens authentication and ensures that only authorized clients can initiate connections, it does not sanitize or validate HTTP-level header content. This creates a scenario where a trusted, authenticated client—presented via a valid client certificate—can still send crafted requests containing malicious CRLF sequences. Because mTLS confirms the client is known, the server may place higher trust in the request context, potentially bypassing stricter input checks that would otherwise be applied. The combination therefore exposes a gap: authentication is strong, but input validation on headers remains weak. An attacker who can obtain or spoof a valid client certificate can probe endpoints that reflect headers, such as a redirect based on a user-supplied URL parameter, and exploit CRLF to inject additional headers or split the response. This can lead to cache poisoning, cross-site scripting via injected headers, or bypassing some security controls that rely on header integrity. Rocket’s routing and request guards operate at a higher abstraction, so developers might assume that mTLS protects the entire request surface, but the framework still parses raw HTTP headers after TLS termination. Consequently, CRLF injection remains a vulnerability at the HTTP layer regardless of mTLS. The risk is especially relevant for APIs or endpoints that accept dynamic values for headers or redirects, where unsanitized input is concatenated into header values. Because middleBrick scans unauthenticated attack surfaces and includes header injection checks among its 12 parallel security checks, it can detect such CRLF patterns even when mTLS is in place, highlighting the need for output encoding and strict validation independent of transport-layer protections.

Mutual Tls-Specific Remediation in Rocket

Remediation focuses on validating and sanitizing any user-controlled data that may influence HTTP headers, independent of mTLS. In Rocket, you should treat all header inputs as untrusted and apply strict allow-lists and encoding. For dynamic header values, such as redirects, avoid directly inserting user input. Instead, use a controlled mapping or validation logic. Below are concrete Rocket code examples demonstrating safe practices with mTLS configured.

Example 1: Safe Redirect with mTLS

Ensure the redirect target is validated against a set of allowed domains or paths, and do not reflect raw input into the Location header.

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

#[get("/redirect")]
fn safe_redirect(target: rocket::State<AllowedTargets>, uri: rocket::Request<'_>) -> Result<Redirect, Status> {
    let requested = uri.query_value("to").unwrap_or("/default");
    // Validate against a whitelist of allowed paths
    if target.0.contains(&requested.to_string()) {
        Ok(Redirect::to(&requested))
    } else {
        Err(Status::BadRequest)
    }
}

struct AllowedTargets(Vec<String>);

#[rocket::main]
async fn main() -> rocket::Result<()> {
    let allowed = AllowedTargets(vec!["/home".into(), "/profile".into(), "/logout".into()]);
    rocket::build()
        .manage(allowed)
        .mount("/", routes![safe_redirect])
        .launch()
        .await
}

Example 2: Custom Header with Sanitized Input

If you must set custom headers, sanitize input by removing or encoding CR and LF characters.

use rocket::request::Request;
use rocket::response::Responder;
use rocket::{Data, Response};
use std::io::Cursor;

struct SafeResponder { body: String }

impl<'r> Responder<'r> for SafeResponder {
    fn respond_to(self, _: &Request) -> rocket::response::Result<'r> {
        let sanitized = self.body.replace("\r", "\r").replace("\n", "\n");
        let mut response = Response::build();
        response.header(rocket::http::Header::new("X-Custom", sanitized));
        response.ok().map(|cursor| Cursor::new(cursor))
    }
}

#[get("/echo")]
fn echo(value: String) -> SafeResponder {
    SafeResponder { body: value }
}

mTLS Configuration Example

Rocket does not manage TLS settings directly; you typically configure mTLS at the reverse proxy or Rocket.toml when using TLS. Below is an illustrative Rocket.toml setup requiring client certificates. This ensures only clients with valid certificates reach your endpoints, but you must still apply the input validation shown above.

[default.tls]
tls_certificate = "certs/server.crt"
tls_private_key = "certs/server.key"
tls_client_ca = "certs/ca.crt"
tls_client_auth = "require"

By combining mTLS for transport-layer authentication with rigorous header input validation, you mitigate CRLF injection risks. middleBrick can help verify that your endpoints do not reflect unsanitized input into headers, even when mTLS is enforced.

Frequently Asked Questions

Does mTLS prevent CRLF injection in Rocket?
No. Mutual Tls authenticates clients at the TLS layer but does not sanitize HTTP header content. CRLF injection is an application-layer issue and must be addressed through input validation and output encoding in Rocket, regardless of mTLS.
Can middleBrick detect CRLF injection when mTLS is enabled?
Yes. middleBrick performs black-box scanning against unauthenticated attack surfaces and includes checks for header injection patterns. It can identify CRLF injection vectors in Rocket endpoints even when mTLS is in use, because it tests at the HTTP layer after TLS termination.