HIGH crlf injectionactixfirestore

Crlf Injection in Actix with Firestore

Crlf Injection in Actix with Firestore — how this specific combination creates or exposes the vulnerability

Crlf Injection occurs when user-controlled data is reflected into HTTP headers without proper sanitization, allowing an attacker to inject newline characters (\r\n) to split the header chain. In an Actix web service that integrates with Google Firestore, this typically happens when response metadata—such as custom headers or redirect locations—are derived from Firestore document fields without validation.

Consider an Actix handler that reads a user profile document from Firestore and sets a custom header X-User-Status from a document field. If the field contains a sequence like injected\r\nSet-Cookie: auth=evil, and the value is passed directly into the response header, the injected CRLF sequence splits the header line. The server may then append Set-Cookie: auth=evil as an additional header, enabling session fixation or cookie injection. Firestore itself does not introduce CRLF Injection; it becomes a vector when Actix reflects untrusted Firestore data into HTTP headers, response lines, or redirect URLs.

An example vulnerable pattern in Actix involves reading a document and using HttpResponse::Ok() with header insertion:

use actix_web::{web, HttpResponse};
use google_cloud_rust::firestore::client::Client;

async fn get_user_status(client: web::Data<Client>, user_id: web::Path<String>) -> HttpResponse {
    let doc = client.collection("users").doc(&user_id).get().await.unwrap();
    let status: String = doc.get("status").unwrap_or("active".to_string());
    HttpResponse::Ok()
        .insert_header(("X-User-Status", status.as_str()))
        .finish()
}

If the Firestore field status contains injected\r\nSet-Cookie: auth=evil, the resulting HTTP response will have an additional Set-Cookie header. This can lead to response splitting, cache poisoning, or session manipulation. The risk is compounded if the Actix service also performs redirects using Firestore data, such as a redirect_url field, where CRLF injection can break the redirect chain and inject malicious locations.

Because Firestore stores arbitrary strings, any field used in headers, location redirects, or response lines must be treated as untrusted. The combination of Actix's flexible response construction and Firestore's permissive string storage creates a scenario where CRLF injection is possible if input validation and output encoding are omitted.

Firestore-Specific Remediation in Actix — concrete code fixes

Remediation centers on disallowing CRLF characters in any data that flows into HTTP headers or status lines, and validating Firestore document fields before use. Below are concrete, Firestore-aware fixes for Actix handlers.

1. Sanitize Firestore string fields before using them in headers. Define a validation helper that rejects control characters, especially \r and \n:

fn sanitize_header_value(value: &str) -> Option<String> {
    if value.chars().any(|c| c == '\r' || c == '\n') {
        return None;
    }
    Some(value.to_string())
}

async fn get_user_status_safe(client: web::Data<Client>, user_id: web::Path<String>) -> HttpResponse {
    let doc = client.collection("users").doc(&user_id).get().await.unwrap();
    let status: String = doc.get("status").unwrap_or("active".to_string());
    match sanitize_header_value(&status) {
        Some(clean) => HttpResponse::Ok()
            .insert_header(("X-User-Status", clean))
            .finish(),
        None => HttpResponse::BadRequest().body("Invalid status value"),
    }
}

This ensures that any Firestore status field containing CRLF is rejected before it reaches the response builder.

2. Use structured data for redirects instead of raw Firestore strings. If you must redirect based on Firestore data, resolve the target against a whitelist or canonical mapping rather than storing raw URLs:

async fn get_redirect(client: web::Data<Client>, page_id: web::Path<String>) -> HttpResponse {
    let doc = client.collection("pages").doc(&page_id).get().await.unwrap();
    let path: String = doc.get("path").unwrap_or("/default".to_string());
    // Validate path is a safe relative route
    if !path.starts_with('/') || path.contains("\r") || path.contains("\n") {
        return HttpResponse::BadRequest().body("Invalid redirect target");
    }
    HttpResponse::SeeOther()
        .insert_header(("Location", path))
        .finish()
}

This prevents CRLF injection into the Location header, a common attack surface for response splitting.

3. Apply output encoding when reflecting Firestore data in the response body. Even when not using headers, embedding raw Firestore strings in HTML or JSON can lead to injection elsewhere. For JSON responses, serialization libraries typically handle escaping, but be cautious with concatenated strings:

async fn user_profile_json(client: web::Data<Client>, user_id: web::Path<String>) -> HttpResponse {
    let doc = client.collection("users").doc(&user_id).get().await.unwrap();
    let bio: String = doc.get("bio").unwrap_or("".to_string());
    // Ensure serialization escapes control characters; do not manually concatenate
    let response = serde_json::json!({ "bio": bio });
    HttpResponse::Ok().json(response)
}

By treating Firestore string outputs as untrusted and applying consistent sanitization—especially for headers and redirects—you mitigate CRLF Injection risks while retaining the flexibility of Firestore as a backend store in Actix.

Frequently Asked Questions

Can CRLF Injection be exploited through Firestore document fields in Actix?
Yes, if Actix reflects untrusted Firestore field values into HTTP headers, status lines, or redirect locations without removing or escaping CRLF characters, an attacker can inject additional headers or split the response, leading to response splitting or cache poisoning.
Does Firestore provide built-in protection against CRLF Injection for Actix integrations?
Firestore stores strings as provided and does not sanitize for HTTP context. It is the application’s responsibility to validate and sanitize any Firestore data before using it in HTTP headers, locations, or any other context where CRLF injection is possible in Actix.