Improper resource allocation - Memory leak
Need
Bounding of memory allocations that depend on request data
Context
• Usage of Rust 1.75+ for building application services
• Usage of the actix-web crate for handling HTTP requests
Description
1. Non compliant code
use actix_web::{post, web, HttpResponse};
use serde::Deserialize;
#[derive(Deserialize)]
struct ExportRequest {
record_count: usize,
}
...The `export` handler below reads `record_count` from the JSON body and calls `Vec::with_capacity(body.record_count)` to prepare the export buffer. The size of the allocation is decided by the client. A `record_count` near `usize::MAX` makes `with_capacity` panic with a capacity overflow, and a value just below that limit makes the allocator fail, which Rust treats as fatal: the whole process aborts, not just the request. Smaller but still huge values, such as a few hundred million records, succeed and hold gigabytes of memory, so a handful of concurrent requests exhausts the memory of the host and the operating system kills the service. The same risk applies to `vec![0; n]`, `String::with_capacity(n)`, `HashMap::with_capacity(n)` and `Vec::reserve(n)` when `n` comes from a request, and to request bodies read without a size limit.
2. Steps
• Validate every request-derived size against a fixed maximum before passing it to `Vec::with_capacity`, `vec![...; n]`, `String::with_capacity` or `reserve`.
• Return `400 Bad Request` for sizes above the limit instead of silently allocating.
• Limit request bodies with `web::JsonConfig::limit`, `web::FormConfig::limit` and `web::PayloadConfig::limit`.
• Paginate or stream large results instead of building them in memory.
• Set memory limits for the service container so a single process cannot exhaust the host.
3. Secure code example
use actix_web::{post, web, HttpResponse};
use serde::Deserialize;
const MAX_RECORDS: usize = 10_000;
const MAX_JSON_BYTES: usize = 16 * 1024;
#[derive(Deserialize)]
struct ExportRequest {...The corrected handler rejects any `record_count` above `MAX_RECORDS` with `400 Bad Request` before allocating, so the largest possible allocation is known and small. The `configure` function also limits the JSON body to 16 KiB with `web::JsonConfig`, so large payloads are rejected before they are buffered and deserialized. When the client legitimately needs more data than the limit, the endpoint should paginate or stream the response instead of allocating it all at once.
References
• 317. Improper resource allocation - Memory leak