Http Request Smuggling in Axum with Firestore
Http Request Smuggling in Axum with Firestore — how this specific combination creates or exposes the vulnerability
HTTP Request Smuggling exploits discrepancies in how front-end and back-end parsers handle request boundaries, typically Transfer-Encoding and Content-Length. In an Axum application that uses Firestore as a backend datastore, the risk emerges when Axum routes or middleware process raw HTTP messages before Firestore operations are constructed. Axum is a Rust web framework that relies on strongly typed extractors; if route handlers compose requests by forwarding or buffering bodies in a way that mixes parser interpretations, an attacker can craft requests where the front-facing reverse proxy or load balancer and Axum’s own parsing logic disagree on request boundaries.
Consider an Axum handler that reads a JSON body to determine a Firestore document path or query parameters. If the handler buffers the request body to forward it elsewhere (for example to enrich a Firestore write with additional metadata), and does so without strict content-length enforcement or by relying on Transfer-Encoding: chunked inconsistently, an attacker can smuggle a second request across the boundary. Because Firestore operations often carry authorization-sensitive context (IAM-bound credentials, database rules), a smuggled request might execute unintended reads or writes if the downstream Firestore client uses the same authorization context as the original request. This becomes critical when Axum services authenticate once and reuse a Firestore client across forwarded or batched operations, allowing a smuggled request to inherit permissions it should not have.
Another scenario involves OpenAPI/Swagger spec parsing combined with Firestore integration. If Axum dynamically builds Firestore queries from parsed JSON bodies and the spec contains $ref resolutions that include request bodies, inconsistent body buffering can cause route handlers to interpret the boundary between requests differently than the underlying HTTP stack. The Firestore client may then execute operations based on a body that includes smuggled instructions, such as changing document IDs or overwriting fields. Because middleBrick scans test unauthenticated attack surfaces, such logic flaws can be surfaced without credentials, highlighting how smuggling can bypass expected isolation between tenant operations in a multi-tenant Firestore setup.
Key attack patterns relevant here include CL.TE (Content-Length then Transfer-Encoding) and TE.CL (Transfer-Encoding then Content-Length) smuggling. If Axum routes trust Transfer-Encoding headers while an upstream proxy uses Content-Length, an attacker can craft a request where the proxy terminates one body and Axum parses another, allowing injection of Firestore mutations or queries that change document state or exfiltrate data. Middleware that logs or traces requests may inadvertently amplify risks by buffering bodies in a way that obscures the boundary, making smuggling harder to detect but not less impactful on Firestore integrity.
Firestore-Specific Remediation in Axum — concrete code fixes
Remediation focuses on strict HTTP message parsing, deterministic body handling, and isolating Firestore operations from ambiguous request boundaries. In Axum, prefer using typed extractors such as Json
Example: Safe Firestore document write with strict body parsing
use axum::{routing::post, Router, extract::State, http::StatusCode};
use firestore::FirestoreDb;
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;
use tower_http::trace::TraceLayer;
#[derive(Deserialize, Serialize)]
struct CreateNote {
document_id: String,
content: String,
}
async fn create_note(
State(db): State,
Json(payload): Json,
) -> Result {
// Use a deterministic document reference; avoid dynamic paths from untrusted input
let doc_ref = db.collection("notes").document(&payload.document_id);
doc_ref.create(&payload.content).await.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
Ok(StatusCode::CREATED)
}
#[tokio::main]
async fn main() {
let db = FirestoreDb::new("my-project").expect("valid project");
let app = Router::new()
.route("/notes", post(create_note))
.with_state(db)
.layer(TraceLayer::new_for_http());
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
Example: Rejecting ambiguous headers to prevent smuggling
use axum::{routing::post, Router, Extension, http::request::Parts, middleware::Next};
use std::task::{Context, Poll};
use tower_http::services::ServeDir;
/// Middleware that rejects requests with both Content-Length and Transfer-Encoding.
pub async fn strict_header_middleware(
mut parts: Parts,
next: Next,
) -> Result {
let has_cl = parts.headers.get("content-length").is_some();
let has_te = parts.headers.get("transfer-encoding").is_some();
if has_cl && has_te {
return Err((StatusCode::BAD_REQUEST, "ambiguous content-length and transfer-encoding"));
}
Ok(next.run(parts).await)
}
async fn write_with_validation(
Extension(db): Extension,
Json(payload): Json,
) -> Result {
// Firestore write logic here
Ok("ok".to_string())
}
fn app() -> Router {
Router::new()
.route("/write", post(write_with_validation))
.layer(Extension(db))
.layer(axum::middleware::from_fn(strict_header_middleware))
}
Firestore client hygiene
Ensure Firestore clients are configured with least-privilege IAM roles and that database rules validate document IDs and field values. Avoid constructing document paths directly from untrusted input; sanitize and validate before using paths. For multi-tenant designs, scope the Firestore client per tenant to prevent cross-tenant writes even if a smuggling attempt manages to alter routing. middleBrick scans can surface missing header validation and overly permissive Firestore rules, so integrate scans into CI/CD using the GitHub Action to fail builds when risky patterns are detected.
Use the CLI to perform regular scans: middlebrick scan <url>. The dashboard allows you to track security scores over time and set alerts with the Pro plan to notify on regressions. If you use AI coding assistants, the MCP Server can run scans directly from your IDE, providing rapid feedback during development.
Frequently Asked Questions
How can I test my Axum + Firestore API for HTTP request smuggling without credentials?
middlebrick scan <your-api-url>. It will probe header parsing and body handling boundaries, surfacing smuggling risks against Firestore endpoints without requiring authentication or source code access.