Integer Overflow in Actix with Firestore
Integer Overflow in Actix with Firestore — how this specific combination creates or exposes the vulnerability
An integer overflow in an Actix web service becomes high risk when processed values are used to interact with Google Cloud Firestore. In Rust, arithmetic operations on primitive integer types do not automatically check for overflow in release builds; a sufficiently large user-supplied integer can wrap around, producing a small or unexpected value. When that value is used to compute document IDs, array indices, limits for paginated queries, or numeric fields stored in Firestore, the wrapped result can cause logic bypasses, data corruption, or unintended access to other users’ data.
Consider a document counter or a numeric field such as account_balance or allocated_units. If an Actix handler performs unchecked addition or multiplication on incoming JSON numbers and then writes the result to Firestore, an overflow can turn a large positive number into a small one. For example, a user ID computed as user_base + offset might wrap and map to another user’s document, enabling a BOLA/IDOR condition across Firestore documents. Similarly, a limit parameter that overflows may remove pagination constraints, causing excessive data retrieval or triggering resource-exhaustion behaviors on the Firestore read path.
Firestore itself enforces constraints on document ID sizes and numeric ranges, but an overflowed value that reaches Firestore may still be accepted while violating application semantics. Because Firestore operations are often batched or used in listener/streaming patterns, an overflowed counter or index might silently corrupt multiple entities or cause duplicated writes. In an Actix service, this typically occurs when numeric deserialization, business logic, and Firestore writes are not consistently guarded with checked arithmetic and server-side validation.
In an LLM/AI security context, an overflowed numeric field could affect features that monitor usage or cost. For instance, token counts or cost accumulators that overflow might underreport consumption, undermining cost-exfiltration detection during active prompt injection tests. The scanner’s inventory management and unsafe consumption checks may flag mismatched numeric invariants between API behavior and Firestore-stored aggregates as an anomaly, highlighting the need for strict validation before writes.
To detect this combination, middleBrick runs parallel checks: input validation to ensure numeric fields remain within safe ranges, property authorization to confirm ownership of Firestore documents accessed by computed identifiers, and inventory management to spot inconsistencies in server-side aggregates. Because no assumptions are made about internal architecture, the scanner focuses on observable behavior—such as unexpected document access or malformed responses—when an API endpoint accepts integers that eventually reach Firestore.
Firestore-Specific Remediation in Actix — concrete code fixes
Remediation centers on preventing invalid integer values from reaching Firestore and ensuring server-side computation is robust. Use Rust’s checked arithmetic (e.g., checked_add, checked_mul) and validate ranges before constructing document references or numeric fields. Treat all incoming numbers as untrusted and recompute identifiers and aggregates on the server using canonical user identifiers rather than relying on client-supplied values.
Below are concrete Actix handler examples with Firestore integration that demonstrate secure patterns.
use actix_web::{web, HttpResponse, Result};
use google_cloud_firestore::client::Client;
use google_cloud_firestore::document::Document;
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
struct UpdateBalancePayload {
user_id: String,
delta: i64,
}
async fn update_balance(
payload: web::Json,
firestore_client: web::Data<Client>,
) -> Result<HttpResponse> {
let payload = payload.into_inner();
// Validate inputs before any arithmetic.
if payload.user_id.is_empty() {
return Ok(HttpResponse::BadRequest().json("invalid user_id"));
}
// Use checked arithmetic to prevent overflow.
let current: i64 = get_current_balance_from_firestore(&firestore_client, &payload.user_id).await?
.unwrap_or(0);
let new_balance = current.checked_add(payload.delta)
.ok_or_else(|| actix_web::error::ErrorBadRequest("integer overflow"))?;
// Ensure non-negative business invariants.
if new_balance < 0 {
return Ok(HttpResponse::BadRequest().json("balance cannot be negative"));
}
// Write back to Firestore using a server-owned document path.
let doc_path = format!("balances/{{}}", payload.user_id);
let doc = Document::new(&doc_path, None, Some(serde_json::to_value(new_balance)?));
firestore_client.set_doc(doc, None).await?;
Ok(HttpResponse::Ok().json("balance updated"))
}
async fn get_current_balance_from_firestore(
client: &Client,
user_id: &str,
) -> Result<Option<i64>, actix_web::error::Error> {
let doc_path = format!("balances/{{}}", user_id);
let doc = client.get_doc(&doc_path, None).await.map_err(|e| {
actix_web::error::ErrorInternalServerError(format!("firestore error: {{}}", e))
})?;
if let Some(value) = doc.map(|d| d.deserialize_field("balance").unwrap_or(0)) {
Ok(Some(value))
} else {
Ok(None)
}
}
Key practices reflected in the example:
- Validate identifiers and numeric inputs before use; reject empty or malformed identifiers.
- Perform arithmetic with checked operations; return a clear 400 error on overflow rather than allowing wrap-around.
- Recompute server-side paths (e.g.,
balances/{user_id}) using trusted identifiers instead of letting clients dictate document keys that could be influenced by overflowed values. - Ensure non-negative invariants where required, and enforce them before writing to Firestore.
For pagination and limits, apply the same principles: validate limit/offset against server-side minima and maxima, use checked arithmetic when adjusting them, and avoid passing raw client integers directly into Firestore queries. middleBrick’s Pro plan supports continuous monitoring for such numeric invariants, and the GitHub Action can fail builds when unsafe patterns are detected in source changes.