Improper resource allocation
Need
Prevention of integer overflow in arithmetic on request-controlled values
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::{get, web, HttpResponse};
const UNIT_PRICE_CENTS: u32 = 100;
#[get("/price/{quantity}")]
async fn price(path: web::Path<u32>) -> HttpResponse {
let quantity = path.into_inner();
// Wraps silently in release builds: 42949673 * 100 == 4...The `price` handler below multiplies the `quantity` taken from the URL by a unit price, both as `u32`, with the `*` operator. Rust only checks integer overflow in debug builds. In release builds, which are the ones deployed, `*` silently wraps around modulo 2^32, so a quantity such as `42949673` makes `42949673 * 100` wrap to `4`. The attacker orders tens of millions of units for a total of 4 cents. The same wrapping can turn a size calculation into a tiny buffer, bypass a limit check, or produce a negative-looking balance. In debug builds, or with `overflow-checks` enabled, the same input makes the handler panic instead, which lets an attacker crash workers on demand.
2. Steps
• Validate request-controlled numbers against explicit business limits before using them in arithmetic.
• Use `checked_add`, `checked_sub`, `checked_mul` and `checked_div` on values that come from requests, and handle the `None` case.
• Widen integers, for example from `u32` to `u64`, before multiplying values that represent money, sizes or counts.
• Enable `overflow-checks = true` in the release profile of `Cargo.toml` so unchecked overflow panics instead of wrapping silently.
• Enable the `clippy::arithmetic_side_effects` lint in modules that handle prices, balances or buffer sizes.
3. Secure code example
use actix_web::{get, web, HttpResponse};
const UNIT_PRICE_CENTS: u64 = 100;
const MAX_QUANTITY: u32 = 10_000;
#[get("/price/{quantity}")]
async fn price(path: web::Path<u32>) -> HttpResponse {
let quantity = path.into_inner();...The corrected handler validates the quantity against a business limit before any arithmetic, and computes the total with `checked_mul` in `u64`. The explicit limit rejects requests that no legitimate customer would send with `400 Bad Request`. `checked_mul` returns `None` instead of wrapping or panicking, so even if the limits change later, an overflow becomes an error response rather than a wrong price. Widening to `u64` gives the calculation room for any valid order. The standard library also offers `saturating_*` and `overflowing_*` methods, and `overflow-checks = true` in the release profile turns any remaining unchecked arithmetic into a panic instead of a silent wrong value.
References
• 067. Improper resource allocation