Skip to main content

Elixir Protobuf CVE-2026-54451

| EUVDEUVD-2026-82368 HIGH
Uncontrolled Recursion (CWE-674)
2026-07-15 https://github.com/elixir-protobuf/protobuf GHSA-rv48-qqj5-crxg
8.2
CVSS 4.0 · Vendor: https://github.com/elixir-protobuf/protobuf
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Identify endpoint decoding recursive protobuf schema
  2. Delivery
    Craft tiny deeply-nested wire-format body
  3. Exploit
    POST as application/x-protobuf
  4. Execution
    Decoder recurses once per nesting level
  5. Persist
    Memory/CPU/scheduler exhausted
  6. Impact
    Node taken offline (DoS)

Vulnerability Assessment

Weakness
CWE
ASVS 5.0
V15 - Secure Coding and Architecture Recursion depth limits
Exploitation Conditions

Exploitable only when a network-reachable service built on the Elixir/Erlang Hex protobuf library (>=0.8.0, <0.16.1) decodes attacker-influenced protobuf bytes into a message type whose schema is self-referential or cyclic (e.g. message Tree { Tree child = 1; }, common for comment threads, org charts, file trees, and ASTs). No authentication or user interaction is required (PR:N/UI:N), and default configuration is affected because no recursion-depth bound existed before 0.16.1. The key LIMITING factor is the schema requirement (reflected as AT:P): a service that only decodes flat/non-recursive message types is not exploitable. Mitigation without upgrade would require avoiding recursive schemas or bounding input depth; the fix adds a configurable :max_nesting_depth defaulting to 100.

Impact

This is a legitimate, well-substantiated availability threat rather than an inflated high-CVSS score, but its real-world reach is narrower than the 8.2 base score suggests. The vendor CVSS 4.0 vector (AV:N/AC:L/AT:P/PR:N/UI:N) shows a network-reachable, low-complexity, unauthenticated flaw whose only impact is availability (VC:N/VI:N/VA:H) - a pure denial of service, consistent with CWE-674 (uncontrolled recursion). The single most important signal is AT:P (Attack Requirements: Present): exploitation is not universal against every service using this library - it requires the target to decode untrusted input into a self-referential or cyclic protobuf message type. Publicly available PoC code raises operational risk (the advisory contains a step-by-step exploit and both the introducing and fixing commits are public), but this is exploit availability, NOT active exploitation - the CVE is not in CISA KEV and no EPSS score is provided in the input, so there is no evidence of exploitation in the wild. No confidentiality or integrity impact exists, so this cannot be chained to code execution or data theft; the worst outcome is node/service unavailability. Net priority: patch promptly on any Elixir/Erlang service that decodes attacker-influenced protobuf into recursive schemas, but treat lower-risk than an RCE. Note the vector is CVSS 4.0 only - no 3.1 vector was supplied by the vendor.

Exploit ScenarioDerived

An attacker identifies an Elixir/Erlang HTTP endpoint that decodes protobuf bodies into a self-referential message type (e.g. a comment-thread, org-chart, file-tree, or AST schema). They POST a small (few KB-few MB) application/x-protobuf body that nests an embedded field hundreds of thousands to millions of levels deep, forcing the decoder to recurse once per level and exhaust memory and CPU on a scheduler. A handful of such concurrent requests takes the BEAM node offline; a public step-by-step PoC exists in the GHSA advisory.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
Patch available 0.3% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv2 – Sep 17, 2026

Unbounded recursion in the Elixir protobuf Hex package (versions >= 0.8.0, < 0.16.1) lets unauthenticated remote attackers take down any service that decodes untrusted protobuf bytes into a self-referential or cyclic message type, because each nested embedded message is decoded with a non-tail recursive call that retains a live stack and heap frame on the BEAM. A body of only a few KB to a few MB can nest an embedded field hundreds of thousands to millions of levels deep, consuming hundreds of MB of memory and seconds of CPU per request and pinning a scheduler, so a handful of concurrent requests can starve and crash the node. Publicly available exploit code exists, and the vendor has released a patch in 0.16.1 that enforces a configurable :max_nesting_depth defaulting to 100, matching Google's C++/Java reference implementations; exploitation is conditional on the target schema actually being recursive (reflected as CVSS 4.0 AT:P), so services decoding only flat message types are not affected despite the 8.2 base score.

Earlier versions of this analysis (1)
v1 Jul 15, 2026 - 18:06

Denial of service in the Elixir/Erlang Hex package protobuf (>= 0.8.0, < 0.16.1) allows an unauthenticated remote attacker to crash any service that decodes untrusted protobuf messages into a self-referential or cyclic message type. Because Protobuf.Decoder performs unbounded, non-tail recursion over embedded message fields, a small request body (a few KB to a few MB) can nest a field hundreds of thousands to millions of levels deep, forcing the BEAM to retain one stack/heap frame per level until it exhausts memory and pins a scheduler; a handful of concurrent requests take the node offline. This is a request-amplification DoS with a publicly available proof-of-concept, but no CISA KEV listing and no evidence of active exploitation; no CVSS or EPSS score is provided in the source data.

RemediationAI

Upgrade to protobuf 0.16.1, the vendor-released fixed version (release notes: https://github.com/elixir-protobuf/protobuf/releases/tag/v0.16.1; advisory: https://github.com/elixir-protobuf/protobuf/security/advisories/GHSA-rv48-qqj5-crxg), which threads a depth counter through decoding and raises Protobuf.DecodeError once nesting exceeds a limit defaulting to 100; after upgrading, Protobuf.decode/3 accepts a :max_nesting_depth option so you can lower the threshold for schemas whose realistic nesting is shallow (too-low values will reject legitimate deeply nested data, so set it above your observed maximum). If upgrading is not immediately possible, compensating controls are limited because the request body can be as small as a few KB, so blanket HTTP body-size limits are insufficient on their own; more effective options are to avoid or restructure self-referential and cyclic schemas (flattening a recursive Tree into a repeated/adjacency representation eliminates the recursion entirely, at the cost of application changes), to pre-scan or proxy-reject length-delimited payloads whose nesting depth exceeds ~100 before handing them to the library (adds parsing CPU per request), to restrict which endpoints accept application/x-protobuf from untrusted clients and rate-limit per connection (reduces but does not remove the amplification risk), and to isolate protobuf-decoding workloads so a crashed node does not take unrelated services down. Note that the fix commits 21ec7c5bec4fec74e10c1de0d5d1a2d8152ac5d4 and b8efa97790eece3d2d0e8e7c31a45ed409fe5338 implement the upstream change, while 0.16.1 is the version to track in dependency manifests; there is no evidence of active exploitation in CISA KEV, but publicly available exploit code exists and unauthenticated remote exploitation is confirmed by the vendor advisory.

Affected VersionsENISA

Protobuf 0.8.0, < 0.16.1

Affected Packages

euvd protobuf_0_8_0 fix: 0.16.1

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 1 package in euvd

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

The issue is CWE-674 (Uncontrolled Recursion) in the pure-Elixir protobuf wire-format decoder shipped in the Hex package protobuf (CPE pkg:erlang/protobuf). Protocol Buffers encodes an embedded message field as wire type 2 (length-delimited): a one-byte field tag plus a varint length prefix followed by the raw sub-message bytes. Protobuf.Decoder.value_for_field/3 handles that embedded?: true branch (lib/protobuf/decoder.ex:218-243) by calling decode(bin, type) recursively, which re-enters build_message -> handle_value -> value_for_field. The recursive call is not in tail position, so every level keeps a live frame; nothing in the decoder tracked or bounded nesting depth, and each additional attacker-chosen level costs only a byte of tag plus a varint, giving an extreme amplification ratio between payload size and recursion depth. On the BEAM, deep recursion and the resulting GC pressure run inside an Erlang process on a scheduler, so memory exhaustion and scheduler pinning translate directly into cluster-wide unavailability rather than a clean per-request failure. Google's C++ and Java implementations cap nesting at 100 precisely for this reason; the Elixir decoder enforced no comparable bound before the fix. The patched code threads a {current_depth, max_nesting_depth} pair through decode/3, build_message, handle_value and value_for_field, raising Protobuf.DecodeError past the limit (default 100) and exposing :max_nesting_depth as a per-call option.

Know when Elixir gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (https://github.com/elixir-protobuf/protobuf) PRIMARY 8.2 HIGH
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
vuln.today AI 7.5 HIGH

Remote, unauthenticated, low-complexity request causes availability-only impact; CVSS 3.1 lacks an attack-requirement metric so the self-referential-schema precondition is not separately captured (base 7.5).

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
4.0 AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Red Hat 7.5 HIGH

Primary rating from Vendor (https://github.com/elixir-protobuf/protobuf).

CVSS VectorVendor: https://github.com/elixir-protobuf/protobuf

Attack Vector
Network
Attack Complexity
Low
Attack Requirements
Present
Privileges Required
None
User Interaction
None
Vulnerable system: Confidentiality
None
Vulnerable system: Integrity
None
Vulnerable system: Availability
High
Subsequent system: Confidentiality
None
Subsequent system: Integrity
None
Subsequent system: Availability
None

Lifecycle Timeline

3
Analysis Updated
Sep 17, 2026 - 19:30 vuln.today
v2 - CVSS changed
CVSS changed
Sep 17, 2026 - 19:22 NVD
8.2 (HIGH)
CVE Published
Jul 15, 2026 - 17:44 cve.org
HIGH

DescriptionCVE.org

Summary

Unbounded recursion depth in Protobuf.Decoder (Hex package protobuf, versions >= 0.8.0, < 0.16.1) lets an unauthenticated attacker crash any service that decodes untrusted protobuf messages whose schema contains a self-referential or cyclic message type. A small request body (a few KB to a few MB) that nests an embedded field hundreds of thousands to millions of levels deep forces the BEAM to recurse once per level, exhausting memory and pinning a scheduler. A handful of such requests can take the node offline (a request-amplification denial of service).

Details

Protobuf.Decoder.value_for_field/3 handles embedded message fields in its embedded?: true branch at lib/protobuf/decoder.ex:218-243. For an embedded field it calls decode(bin, type) recursively, which re-enters build_message → handle_value → value_for_field. The recursive call is not in tail position (its result is consumed by the surrounding decode after it returns), so every nesting level retains a live frame on the process stack and heap.

There is no recursion-depth counter anywhere in the decoder. For any schema with a self-referential message type (e.g. message Tree { Tree child = 1; }, a common shape for comment threads, org charts, file trees, and ASTs) or any cycle of message types, the attacker controls the nesting depth entirely through the input bytes. Each additional level costs only a 1-byte field tag plus a varint length prefix, so depth grows roughly inversely with payload size: a tiny body buys an enormous recursion depth.

Reference protobuf implementations (Google's C++, Java, etc.) cap recursion at 100 specifically to prevent this. The Elixir decoder enforces no comparable bound, so the recursion continues until the process exhausts memory, blows the stack, or starves the scheduler doing GC over the deep structure.

The fix threads a depth counter through decode / build_message / handle_value / value_for_field (or holds it in the process dictionary for the duration of the top-level decode) and raises Protobuf.DecodeError once it exceeds a configurable limit, defaulting to 100 to match the reference implementations.

PoC

  1. Define a self-referential schema: defmodule Tree do use Protobuf, syntax: :proto3; field(:child, 1, type: Tree) end.
  2. Build a wire-format body inner-to-outer: at each of depth levels prepend <<0x0A, length_varint(inner_size), inner>> (tag 0x0A = field 1, wire type 2). Use an iolist with a running byte-size to keep generation O(depth).
  3. POST the body (a few MB at depth = 1_000_000) as application/x-protobuf to any endpoint that calls Tree.decode/1.
  4. The non-tail decode(bin, type) in value_for_field/3 re-enters once per nesting level, accumulating a frame per level. The decode burns seconds of CPU and hundreds of MB on the victim node; a few concurrent requests exhaust it.

Impact

Unauthenticated, network-reachable request-amplification denial of service against any service that decodes attacker-influenced protobuf bytes into a self-referential or cyclic message type. A single small request can consume seconds of CPU and hundreds of MB of memory on the victim; a few concurrent requests can take the node offline.

Resources

  • Introduction commit: https://github.com/elixir-protobuf/protobuf/commit/21ec7c5bec4fec74e10c1de0d5d1a2d8152ac5d4
  • Patch commit: https://github.com/elixir-protobuf/protobuf/commit/b8efa97790eece3d2d0e8e7c31a45ed409fe5338

Executive ViewAI

Why It Matters

A high-severity denial-of-service flaw in the Elixir protobuf library (versions 0.8.0 through 0.16.0) lets a small, specially crafted message exhaust memory and CPU on any Elixir or Erlang service that decodes untrusted protobuf data into a self-referential or cyclic message schema, potentially crashing an entire node with only a few concurrent requests. Because protobuf decoding sits on core, often customer-facing request paths, a successful attack can produce prolonged outages and cascading failures across dependent applications and downstream consumers. With publicly available exploit code and a vendor fix already released in 0.16.1, this is a near-term remediation priority for teams running the library in production.

Business Impact: High
Compensating Controls

Apply vendor patch.

Threat Intelligence Overview

EPSS Score
0.3%
Top 77% exploitable
Prevalence
Low
main Elixir protobuf library but niche BEAM/Erlang language ecosystem
Threat Intel
1
1 source
Exploit
POC
Public exploit code exists
Data Quality
6 sources
Confidence: High

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity HIGH
CISA KEV No
Public POC Yes
EPSS 0.3%
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Out-of-Cycle
Exploitation· derived
Poc
System Exposure· derived
Open
Automatable· derived
Yes
Human Impact
High

Priority Score

61
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +41
PoC: +20
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Denial of Service attacks render applications or systems unavailable by overwhelming resources or triggering failure conditions.

More in Elixir

View all
CVE-2026-91187 CRITICAL
9.3 Sep 24

Improper JWT signature verification in Dashbit's nimble_zta (0.1.2 up to but not including 0.1.3) lets an unauthenticate

CVE-2026-76949 CRITICAL
9.1 Sep 17

Session-swapping authentication bypass in the Elixir library AshAuthentication (versions 4.10.0 before 4.15.0 and 5.0.0-

CVE-2026-91039 CRITICAL
9.1 Sep 17

Authentication bypass in the Elixir library ash_authentication lets an attacker who operates one federated identity-prov

CVE-2026-88952 CRITICAL
9.1 Sep 17

Account takeover in AshAuthentication (Elixir/Ash) 4.14.0 through 4.14.x and 5.0.0-rc.10 through 5.0.0-rc.13 lets unauth

CVE-2026-77866 CRITICAL
9.0 Sep 15

Server-Side Request Forgery protection bypass in the Elixir safeurl library (versions 0.1.0 and later) allows unauthenti

CVE-2026-108529 HIGH
8.7 Oct 26

Unauthenticated remote CPU exhaustion in mtrudel Bandit's HTTP/2 server (versions before 1.14.0) is achievable by holdin

CVE-2026-110499 HIGH
8.7 Oct 26

Unbounded per-connection memory and CPU growth in the Elixir Bandit HTTP/2 server (0.3.6 up to 1.14.0) lets an unauthent

CVE-2026-111101 HIGH
8.7 Oct 26

Unauthenticated remote denial of service in the Elixir HTTP server Bandit (mtrudel/bandit) from 0.1.0 before 1.14.0 lets

CVE-2026-113436 HIGH
8.7 Oct 26

Unauthenticated remote attackers can consume disproportionate server CPU on Bandit (mtrudel/bandit, Elixir/Erlang) by se

CVE-2026-104635 HIGH
8.2 Oct 09

Memory-exhaustion denial of service in the elixir-protobuf library (protobuf) from 0.8.0 onward allows an unauthenticate

CVE-2026-94201 HIGH
8.2 Oct 05

Atom table exhaustion in the Ash framework (Elixir) allows an unauthenticated remote attacker to crash a BEAM node by su

CVE-2026-95105 HIGH
8.2 Oct 06

Ciphertext tampering in the Cloak Elixir encryption library (danielberkompas/cloak, all versions from 0.1.0-pre onward)

Vendor StatusVendor

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy