# Negative or unvalidated numeric quantity

Quantity, amount or count fields used in totals or stock math without sign or range checks

_Area: Web business logic and race conditions. Seen in 2 disclosed reports; latest 2026-08-04. Updated 2026-10-25._

## How it works
A numeric field from the client (quantity, amount, count) is trusted as-is and fed straight into arithmetic that builds a total, adjusts stock, or moves money. The code assumes the number is positive and within a sane range, but nothing enforces that. A negative value then subtracts from the total instead of adding, or a zero/oversized value breaks the invariant the business logic depends on. The root cause is a missing sign/range check at the trust boundary, not a flaw in the arithmetic itself.

## Where it shows up
- Per-line quantity or price fields in checkout, cart, or bulk-purchase request bodies used directly in total computation [E2](https://bugbountylibrary.com/r/h1%3A771694.md).
- Server-side totals computed naively from client-supplied numbers with no `> 0` or upper-bound guard [E2](https://bugbountylibrary.com/r/h1%3A771694.md).
- Guard flags that short-circuit validation and assume a condition (e.g. record destruction) that does not hold under all option combinations [E3](https://bugbountylibrary.com/r/h1%3A90457.md).
- Any field where a negative or zero value would reverse the intended direction of a balance, stock, or price change.

## How to review
Trace each numeric input from parse to use. The invariant: every quantity/amount used in totals, stock, or balance math must be validated as a positive integer within an allowed range before use, and the server must recompute totals rather than trust client arithmetic. Check that validation runs on the server, not only the client. For guard flags, confirm the assumed condition actually holds for every option combination (e.g. `allow_destroy:false`) before letting the flag skip validation [E3](https://bugbountylibrary.com/r/h1%3A90457.md).

## Variants seen
- Negative per-item quantity in a bulk purchase API reducing cart total to near zero [E2](https://bugbountylibrary.com/r/h1%3A771694.md).
- A `_destroy` flag short-circuiting a `reject_if` proc when `allow_destroy:false`, so rejected changes are applied [E3](https://bugbountylibrary.com/r/h1%3A90457.md).

## Impact and severity
Direct business loss: attacker buys goods for near-zero cost [E2](https://bugbountylibrary.com/r/h1%3A771694.md), or applies changes that validation was meant to block [E3](https://bugbountylibrary.com/r/h1%3A90457.md). Severity rises when the field feeds money or inventory directly and no downstream reconciliation catches the anomaly.

## Why fixes fail
E3 shows a fix (commit a9b4b5d) that introduced the short-circuit assuming destruction, which is false under `allow_destroy:false` — a partial fix that regressed under an option combination. Validate the guard's assumption across all configurations.

## Evidence
- E1: https://bugbountylibrary.com/r/ghsa%3AGHSA-6vh2-wg4h-4vwj.md
- E2: https://bugbountylibrary.com/r/h1%3A771694.md
- E3: https://bugbountylibrary.com/r/h1%3A90457.md
