# CVE-2026-55407: Unbounded Heap Allocation DoS in Anthropic's Buffa Rust Protobuf Library (decode_unknown_field)

> Buffa, Anthropic's Rust protobuf implementation (and the related connectrpc library), contained an unbounded heap-allocation flaw in decode_unknown_field's handling of WireType::StartGroup, allowing a crafted 64 MiB payload of nested minimal varint fields to force ~1.4 GB of heap allocation (~22x amplification) and trigger an OOM crash. Discovered by Endor Labs' AI SAST engine and disclosed via Anthropic's bug bounty program; patched in buffa/connectrpc 0.8.0.

- **Published:** 2026-07-01T00:00:00Z
- **Last reviewed:** 2026-07-01T00:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-1039
- **ID:** TL-2026-1039
- **Severity:** MODERATE (CVSS 6.3)
- **Category:** VULNERABILITY
- **Status:** PATCHED
- **Detections:** 9 · **IOCs:** 16 (full data via the Threadlinqs MCP server — Purple tier)
- **CVEs:** CVE-2026-55407

## Description

CVE-2026-55407 (GHSA-f9qc-qg88-7pq5) is an uncontrolled resource consumption vulnerability in decode_unknown_field, located in buffa/src/encoding.rs, reachable through the default public decode APIs Message::decode, Message::decode_from_slice, and MessageView::decode_view whenever generated code retains unknown fields (preserve_unknown_fields=true, the default).

Two distinct amplification vectors exist in the same function. The first, a flat WireType::LengthDelimited path (encoding.rs lines ~490-499), allocates a Vec<u8> sized directly from an attacker-controlled varint length prefix; a `buf.remaining()` check prevents out-of-bounds reads but places no independent cap on the size of the allocation itself, yielding roughly 2x amplification relative to wire size. The second and more severe vector abuses WireType::StartGroup (encoding.rs lines ~500-520): the decoder loops over nested fields until an EndGroup marker, pushing one UnknownField struct (~40 bytes on 64-bit targets) per iteration. Because a minimal field can be encoded in just 2 wire bytes (a 1-byte tag plus a 1-byte zero varint), an attacker can pack roughly 33.5 million such fields into a single group inside a 64 MiB message, producing about 1.41 GB of live heap - approximately 22x amplification. Recursion depth is bounded, but there is no limit on the number of fields processed per group or per message.

Endor Labs demonstrated the exploit with a wire payload of `0x0b` (StartGroup, field 1) followed by repeated `[0x08, 0x00]` two-byte varint pairs and a closing `0x0c` (EndGroup), decoded against the zero-field `google.protobuf.Empty` message type (exploitable purely via forward-compatible unknown-field retention, with no declared fields required). In a Docker container capped at 256 MiB, the 64 MiB payload reliably produced an OOM-kill (process exit code 137). Buffa's DecodeOptions::DEFAULT_MAX_MESSAGE_SIZE (~2 GiB) bounds the incoming wire size but does not constrain in-memory expansion from group-based unknown-field amplification.

The flaw was found by Endor Labs' AI-assisted static analysis (SAST) engine through data-flow tracing of attacker-controlled wire values into unbounded allocation sinks - a class of bug traditionally hard to automate against memory-safe languages that lack classic unsafe-pointer primitives. It was reported to Anthropic through its bug bounty program, validated by Anthropic, and resolved collaboratively; Anthropic paid a $600 bounty. Buffa and connectrpc 0.8.0 fix the issue by enforcing a configurable per-message limit on the number of retained unknown fields (default: 1,000,000 fields), capping worst-case unknown-field overhead at roughly 40 MB per message. Consumers who do not need unknown-field preservation can also mitigate by regenerating code with preserve_unknown_fields=false, which removes the vulnerable retention path entirely.

No in-the-wild exploitation has been reported; this was a coordinated, pre-emptive disclosure. Real-world severity is deployment dependent: services running multiple replicas behind supervision/auto-restart see graceful, low-impact degradation, while single-instance or unsupervised deployments - and high-concurrency gRPC services accepting the common 4 MiB default message-size limit - face a repeatable, unauthenticated crash-loop DoS with low attacker cost (small payload, no authentication required).

## MITRE ATT&CK

- T1595 Active Scanning
- T1592 Gather Victim Host Information
- T1596 Search Open Technical Databases
- T1594 Search Victim-Owned Websites
- T1588 Obtain Capabilities
- T1587 Develop Capabilities
- T1190 Exploit Public-Facing Application
- T1046 Network Service Discovery
- T1518 Software Discovery
- T1499 Endpoint Denial of Service

## Sources

- [Anthropic's Buffa Rust Library 0-Day Vulnerability Enables DoS Attack](https://cybersecuritynews.com/anthropics-buffa-rust-library-0-day-vulnerability-enables-dos-attack/)
- [Endor Labs' AI SAST Finds Zero Day Memory-Amplification DoS in Anthropic's buffa library](https://www.endorlabs.com/learn/endor-labs-ai-sast-finds-zero-day-cve-2026-55407-buffa)
- [Anthropic buffa Library Hit by Zero-Day DoS Flaw in Rust Protobuf Decoder](https://cyberpress.org/anthropic-buffa-library-flaw/)
- [GHSA-f9qc-qg88-7pq5](https://github.com/advisories/GHSA-f9qc-qg88-7pq5)
- [anthropics/buffa - Rust implementation of protobuf](https://github.com/anthropics/buffa)
- [buffa Releases (v0.8.0)](https://github.com/anthropics/buffa/releases)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-1039
