
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.
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:
LengthDelimitedarm (lines ~490–499): alenvarint taken off the wire sizes avec![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 deliverlenbytes. This is the flagged sink; amplification is a modest ~2x input size.StartGrouparm (lines ~500–520): loops reading nested fields untilEndGroup, pushing each intonested.fields: Vec<UnknownField>.checked_subbounds 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-byteUnknownField— 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
Related in AppSec
Flowise MCP Security Bypass Enables RCE
Inside an Oracle Database SQL Injection Attack | Huntress
OASIS
