Skip to content

Back to the catalog

Endor Labs’ AI SAST Finds Zero Day Memory-Amplification DoS in Anthropic’s buffa library | Blog | Endor Labs
endorlabs.comwriteup

Endor Labs’ AI SAST Finds Zero Day Memory-Amplification DoS in Anthropic’s buffa library | Blog | Endor Labs

Endor Labs describes how its AI SAST engine traced a source-to-sink data flow in Anthropic's Rust protobuf library, buffa, uncovering CVE-2026-55407: an unbounded, attacker-controlled heap allocation in the unknown-field decoder (decode_unknown_field, buffa/src/encoding.rs). Beyond the initially flagged ~2x LengthDelimited allocation flaw, the researcher found the StartGroup arm allows ~22x memory amplification, letting a 64MB payload balloon to ~1.4GB and OOM-kill a capped server, defeating the library's documented "cap input size" mitigation. The piece details the PoC, the fix shipped in buffa/connectrpc 0.8.0 (per-message unknown-field count cap), and a nuanced CVSS 4.0 disclosure discussion with Anthropic over deployment-dependent severity.

TL;DR AI SAST tool finds a 22x memory-amplification DoS (CVE-2026-55407) in Anthropic's Rust protobuf library buffa via unbounded unknown-field decoding.
Document

What it is

Endor Labs' AI SAST engine found CVE-2026-55407 (GHSA-f9qc-qg88-7pq5), a moderate memory-amplification DoS in Anthropic's Rust protobuf library buffa, rated CVSS 4.0 6.3 (Moderate). The flaw is in decode_unknown_field in buffa/src/encoding.rs.

How it works

Two sinks in the same function, one branch apart:

  • LengthDelimited arm (lines ~490–499): a len varint taken off the wire sizes a vec![0u8; len] directly. The only guard, buf.remaining() < len, prevents an out-of-bounds read but does not cap the allocation — it just forces the attacker to actually deliver len bytes. This is the flagged sink; amplification is a modest ~2x input size.
  • StartGroup arm (lines ~500–520): loops reading nested fields until EndGroup, pushing each into nested.fields: Vec<UnknownField>. checked_sub bounds recursion depth but does nothing about field count in a single group. The cheapest nested field is a zero varint at 2 wire bytes, producing a ~40-byte UnknownField — a ~20x structural blow-up, plus ~1.5x transient, giving the ~22x figure that can OOM-kill a process whose memory cap sits above any sane input-size limit.

Preconditions / Affected

Any message decoded from untrusted input using code generated with preserve_unknown_fields=true — which is the default. That forward-compatibility path routes all untrusted input through this function, so most deployments are in scope.

What to do

The page states no patch version and no fix command. The load-bearing detail for an engineer: buffa's own docstring (lines ~463–468) pushes mitigation onto callers via a caller-side input-size cap. That cap holds for the flat LengthDelimited sink (~2x) but does not hold for the StartGroup arm — a tiny bounded input still produces ~22x heap. Do not rely on an input-size limit alone as the defense. The page notes Anthropic responded quickly and discussed severity as deployment-dependent.

Caveats

  • Severity is contested as deployment-dependent; Endor and Anthropic "engaged in productive collaborative discourse on severity depending on deployment."
  • The ~22x figure is an estimate on a 64-bit target (40-byte UnknownField = 4-byte field number + 4 padding + 32-byte enum); the fetched text is truncated mid-sentence on the transient-allocation multiplier.
  • No affected/fixed version range is given in the text.
flowchart TD
    A[Untrusted message<br/>preserve_unknown_fields=true] --> B{decode_unknown_field<br/>wire type?}
    B -->|LengthDelimited| C[vec! len from wire<br/>~2x, input-size cap works]
    B -->|StartGroup| D[loop: push per-tag<br/>UnknownField]
    D --> E[depth bounded,<br/>field count NOT]
    E --> F[~22x heap, cap fails<br/>OOM]

Organisations named here

  • GHSA-f9qc-qg88-7pq5

CVEs named here

  • CVE-2026-55407

Technologies named here

  • buffa
  • Endor Labs AI SAST
  • connectrpc
  • Rust
  • Docker
  • Anthropic
  • Endor Labs
  • CVSS

Techniques named here

  • Denial of Service via excessive memory allocation
  • Recursion depth limiting bypass via field-count