# Unvalidated length in binary parsers

Attacker length, count, or varint reaching allocation, index, or copy without a check

_Area: Memory corruption and native code. Seen in 3 disclosed reports; latest 2026-10-08. Updated 2026-10-23._

## How it works
A binary format carries a length or count field that the parser trusts. The parser assumes the value is non-negative, fits the destination, or matches the stream's real size, and passes it straight to an allocation, index, or copy. When the assumption breaks, the result is an out-of-bounds write, a trap, or a panic that kills the process. The root cause is a missing check at the boundary where attacker bytes become a size or index.

## Where it shows up
- A length read from the stream used directly as a copy count into a fixed buffer [E3](https://bugbountylibrary.com/r/h1%3A1688309.md).
- A varint truncated to a fixed-width int without rejecting negatives [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-86wm-r4c5-2rc9.md).
- Bounds checks that validate only the upper bound, letting negative counts through [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-86wm-r4c5-2rc9.md).
- Sibling code paths where one validates a stream length and the other does not [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-2j4c-ffch-9f23.md).
- A dispatch check that only confirms a minimum header length before handing buffers to callees that never validate structure [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-2j4c-ffch-9f23.md).
- A server-enforced size limit smaller than the client parser's own buffer [E3](https://bugbountylibrary.com/r/h1%3A1688309.md).

## How to review
For every length or count field taken from input, trace it to its sink (allocation, index, copy, loop bound). The invariant: before use, the value must be proven non-negative and no larger than both the remaining input and the destination capacity. Check that the check sits on the path actually taken, not only a sibling path. Confirm the dispatch-level check (e.g. a minimum header length) is not mistaken for structural validation of the payload [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-2j4c-ffch-9f23.md). Compare enforced limits against assumed buffer sizes.

## Variants seen
- Fixed-size stack buffer overflow from an unchecked uint16 chunk length [E3](https://bugbountylibrary.com/r/h1%3A1688309.md).
- Negative varint length reaching a trapping Foundation call [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-86wm-r4c5-2rc9.md).
- Missing length validation in one decryptor while its sibling checks it [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-2j4c-ffch-9f23.md).

## Why fixes fail
E2 shows a bounds check that only tested the upper bound, so negative counts still slipped through. E1 shows validation present in the agile path but absent in the standard path, and the dispatch check (len >= 4) was too weak to stand in for it. E3 notes the server limit (0x200) was smaller than the parser buffer (0x400), so the gap persisted.

## Impact and severity
Outcomes ranged from process-killing panics [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-2j4c-ffch-9f23.md)[E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-86wm-r4c5-2rc9.md) to memory corruption and crashes [E3](https://bugbountylibrary.com/r/h1%3A1688309.md). Severity rises when the parser handles untrusted network or file input in a shared runtime, and when a single malformed message aborts a whole service.

## Evidence
- E1: https://bugbountylibrary.com/r/ghsa%3AGHSA-2j4c-ffch-9f23.md
- E2: https://bugbountylibrary.com/r/ghsa%3AGHSA-86wm-r4c5-2rc9.md
- E3: https://bugbountylibrary.com/r/h1%3A1688309.md
