Endor Labs’ AI SAST Finds Zero Day Memory-Amplification DoS in Anthropic’s buffa library | Blog | Endor Labs
-->
Open source can't be patched at Mythos-scale alone (so we're starting today)<br>Learn More
Learn
Research
Company
LeanAppSec
Pricing
Docs
Login
Book a Demo
Book Demo
By clicking “Accept”, you agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts. View our Privacy Policy for more information.
DenyAccept
18px_cookie
e-remove
Customize your preferences
Essential<br>Required
These items are required to enable basic website functionality.
Marketing
Essential<br>These items are used to deliver advertising that is more relevant to you and your interests.
Analytics
Essential<br>These items help the website operator understand how its website performs, how visitors interact with the site, and whether there may be technical issues.
Personalization
Essential<br>These items allow the website to remember choices you make (such as your user name, language, or the region you are in) and provide enhanced, more personal features.
Remove all cookiesSave & submit
Blog<br>Endor Labs’ AI SAST Finds Zero Day Memory-Amplification DoS in Anthropic’s buffa library<br>We identified an unbounded-allocation data flow in buffa's protobuf decoder that I developed into a ~22x memory-amplification denial of service for CVE-2026-55407.
Written by<br>Peyton Kennedy
Published on<br>June 30, 2026
Updated on<br>June 30, 2026
Topics<br>Open Source<br>Security
Summarize with AI
When I pointed Endor Labs' AI SAST engine at buffa, Anthropic's Rust protobuf library, it flagged a vulnerable data flow I would not have prioritized from a quick read: an unknown-field decoder that allocates heap in proportion to attacker-controlled wire data. The engine called it a potential denial of service via excessive memory allocation. The proportional allocation the engine pointed at is real but modest, roughly 2x the input. Following the same function one branch further led to a second sink that amplifies a tiny input into a heap blow-up of about 22x, which is enough to OOM-kill a process whose memory cap sits well above any sane input-size limit.<br>buffa ships from Anthropic, the same lab that builds frontier models, including the recently released and un-released Mythos and Fable models, so it is about as close to model-assisted, heavily reviewed Rust as you will find. This flaw in the data flow still shipped, and was caught by our AI SAST security engine, following it end to end. The Anthropic team quickly responded to the disclosure and engaged in productive collaborative discourse on severity depending on deployment.<br>This is a good example of Endor Labs AI SAST earning its keep on a memory-safe language. The bug is an allocation-budget flaw on a forward-compatibility code path that every buffa-decoded message routes untrusted input through, and the engine found it by following data, not by pattern-matching a dangerous call.<br>Affected component<br>Tracked as GHSA-f9qc-qg88-7pq5 / CVE-2026-55407, Moderate (CVSS 4.0 6.3). Any message decoded from untrusted input using code generated with preserve_unknown_fields=true (the default) was affected.
Package<br>Ecosystem<br>Affected versions<br>Patched
buffa<br>Rust
0.8.0
connectrpc<br>Rust
0.8.0
The vulnerable code is decode_unknown_field in buffa/src/encoding.rs.<br>How AI SAST identified it<br>The engine traced a length value parsed from wire data straight into a Vec allocation, with no bound between the two beyond fitting in a usize. It reported the flow stage by stage.<br>AI SAST output:
"ruleId": "AI SAST: Potential Denial of Service via excessive memory allocation due to large LengthDelimited field",
"level": "note",
"message": "decode_unknown_field allocates a Vec whose length is taken directly
from a length prefix (len) parsed from the input for WireType::LengthDelimited fields.
There is no upper bound on len beyond fitting into usize and the size of the provided
buffer. A caller can supply an arbitrarily large buffer whose contents specify an
arbitrarily large len, causing this function to attempt a very large allocation and
potentially exhaust memory, resulting in a denial of service.",
"locations": [{ "physicalLocation": {
"artifactLocation": { "uri": "buffa/src/encoding.rs" },
"region": { "startLine": 496 }
}}]
}Identified data flow:
Stage<br>Location<br>Code
Source<br>encoding.rs:491<br>let len = decode_varint(buf)?; — len parsed from wire data
Propagation<br>encoding.rs:492<br>usize::try_from(len) — still unbounded apart from fitting a usize
Propagation<br>encoding.rs:493<br>if buf.remaining()
Sink (alloc)<br>encoding.rs:496<br>let mut data = alloc::vec![0u8; len]; — allocates len bytes
Sink (copy)<br>encoding.rs:497<br>buf.copy_to_slice(&mut data); — copies len bytes in
This is the part of AI SAST I have come to rely on. The engine did not just see a vec! and shrug. It established that len originates in untrusted input, that the only check between source and...