Crlf Injection in Rocket with Bearer Tokens
Crlf Injection in Rocket with Bearer Tokens — 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 HTTP headers, causing header injection or response splitting. In the Rocket web framework for Rust, this risk arises when user-controlled input is reflected into headers such as Location or custom headers without proper validation. When Bearer Tokens are handled in Rocket routes—either as route parameters, query values, or request headers—developer code that directly uses that input to construct headers becomes vulnerable.
Consider a Rocket endpoint that accepts a token from the client and redirects to a profile URL using that token. If the token value is concatenated into a Location header without sanitization, an attacker can supply a token like example.com\r\nSet-Cookie: session=hijacked. Rocket may pass this value to the underlying HTTP layer, resulting in response splitting that can inject additional headers or a second response body. This can lead to HTTP response smuggling, cache poisoning, or client-side cookie manipulation. Even when Bearer Tokens are expected to be opaque strings, treating them as safe without validation is unsafe because their origin may be untrusted (e.g., from a query parameter or a header).
The combination of Rocket’s routing and header APIs with Bearer Token handling increases risk when developers assume framework-level sanitization. Rocket does not automatically neutralize CR or LF characters in header values; it passes them through to the underlying server. If your API uses Bearer Tokens in authorization headers, ensure that any reflection of token-like values into other headers is disallowed or encoded. Complementary checks in middleBrick’s LLM/AI Security and Input Validation scans can surface scenarios where token handling intersects with header manipulation, providing prioritized findings and remediation guidance.
Real-world patterns include concatenating user input into headers via format! or using rocket::response::Redirect with a user-provided URL fragment. Always treat Bearer Token inputs as opaque strings and avoid using them to build headers or URLs directly. Encode or reject CR/LF characters, and prefer framework-level redirects that do not require manual header assembly.
Bearer Tokens-Specific Remediation in Rocket — concrete code fixes
Remediation focuses on strict input validation, safe header construction, and avoiding reflection of token-like values into mutable headers. Below are concrete, safe patterns for Rocket that prevent CR/LF injection when working with Bearer Tokens.
1. Reject or encode CR/LF in token-like inputs
If a route parameter or query value is expected to behave like a Bearer Token, validate that it does not contain CR (\r) or LF (\n) before using it. Use a dedicated validator to keep the sanitization centralized.
use rocket::request::Request; use rocket::http::Status;
fn is_valid_token(token: &str) -> bool {
// Reject CR/LF to prevent header injection
!token.contains('\r') && !token.contains('\n')
}
#[rocket::get("/profile<token>")]
fn profile(token: String) -> Result<String, Status> {
if is_valid_token(&token) {
// Safe to use token in business logic; do not embed in headers
Ok(format!("Valid token length: {}", token.len()))
} else {
Err(Status::BadRequest)
}
}
2. Use Rocket’s built-in redirect safely
When redirecting, avoid building URLs or headers with user input. If you must redirect based on a token, ensure the token is not placed into header values. Instead, use path parameters or opaque identifiers mapped server-side.
use rocket::response::Redirect;
#[rocket::get("/redirect")]
fn redirect_to_home() -> Redirect {
// Safe: no user input in header construction
Redirect::to(uri!(home))
}
3. Explicitly set headers without concatenation
If you must set custom headers, define static values or sanitize dynamic values by removing CR/LF. Do not concatenate token strings into header values.
use rocket::http::Header;
use rocket::response::Response;
#[rocket::catch(400)]
fn bad_request() -> Response {
let mut response = Response::build();
// Safe: static header value
response.header(Header::new("X-Request-ID", "static-123"));
// If you must include a sanitized token, strip CR/LF first:
// let token = sanitize_token(user_token);
// response.header(Header::new("X-Token-Hint", &token));
response.finalize()
}
4. Validate incoming Authorization headers
When expecting Bearer Tokens in the Authorization header, parse and validate them rather than echoing them back into other headers. Reject malformed schemes that include CR/LF.
use rocket::request::{self, Request, FromRequest};
use rocket::http::Status;
struct BearerToken(String);
#[rocket::async_trait]
impl<'r> FromRequest<'r> for BearerToken {
type Error = ();
async fn from_request(request: &'r Request<'>) -> request::Outcome<Self, Self::Error> {
let header = match request.headers().get_one("authorization") {
Some(h) => h,
None => return request::Outcome::Error((Status::Unauthorized, ())),
};
let prefix = "Bearer ";
if !header.starts_with(prefix) {
return request::Outcome::Error((Status::Unauthorized, ()));
}
let token = &header[prefix.len()..];
if !is_valid_token(token) {
return request::Outcome::Error((Status::BadRequest, ()));
}
request::Outcome::Success(BearerToken(token.to_string()))
}
}
By combining strict validation, avoiding header concatenation, and using Rocket’s safe abstractions, you mitigate Crlf Injection risks associated with Bearer Token handling while maintaining a robust API surface.