CVE-2026-104635
Uncontrolled recursion in elixir-protobuf/protobuf JSON decoding of self-referential messages
CVE-2026-104635 is a high vulnerability (CVSS 8.2) in Elixir-protobuf Protobuf, published October 9, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.50%, the 42nd percentile. Fixed in protobuf 0.17.1.
Uncontrolled Recursion vulnerability in Protobuf.JSON.Decode in elixir-protobuf protobuf allows an unauthenticated remote attacker to crash the decoding process via a deeply nested JSON document. Any application that decodes attacker-supplied JSON with Protobuf.JSON.decode/3, Protobuf.JSON.decode!/3, or Protobuf.JSON.from_decoded/3 into a schema that contains a self-referential or cyclic message type is affected.
In lib/protobuf/json/decode.ex, the embedded-message clause of decode_singular/3 recurses into internal_from_json_data/3 once per nesting level without incrementing or checking the decoder's depth counter. The depth guard increase_depth_and_maybe_throw/1 covers only the Google.Protobuf.ListValue and Google.Protobuf.Struct clauses, so the recursion_limit option has no effect on user-defined message types. Each nesting level allocates a stack frame and heap objects, and a sufficiently deep document exhausts the memory of the decoding process. Confidentiality and integrity are not affected.
This issue affects protobuf: from 0.8.0 before 0.17.1.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.2
Uncontrolled recursion in elixir-protobuf/protobuf JSON decoding of self-referential messages
Uncontrolled Recursion vulnerability in Protobuf.JSON.Decode in elixir-protobuf protobuf allows an unauthenticated remote attacker to crash the decoding process via a deeply nested JSON document. Any application that decodes attacker-supplied JSON with Protobuf.JSON.decode/3, Protobuf.JSON.decode!/3, or Protobuf.JSON.from_decoded/3 into a schema that contains a self-referential or cyclic message type is affected.
In lib/protobuf/json/decode.ex, the embedded-message clause of decode_singular/3 recurses into internal_from_json_data/3 once per nesting level without incrementing or checking the decoder's depth counter. The depth guard increase_depth_and_maybe_throw/1 covers only the Google.Protobuf.ListValue and Google.Protobuf.Struct clauses, so the recursion_limit option has no effect on user-defined message types. Each nesting level allocates a stack frame and heap objects, and a sufficiently deep document exhausts the memory of the decoding process. Confidentiality and integrity are not affected.
This issue affects protobuf: from 0.8.0 before 0.17.1.
- Record
CVE-2026-104635- CVSS 4.0
- 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 - Weakness
- CWE-674
- Updated
- 2026-11-02
EUVDEUVD-2026-95562
8.2
Uncontrolled Recursion vulnerability in Protobuf.JSON.Decode in elixir-protobuf protobuf allows an unauthenticated remote attacker to crash the decoding process via a deeply nested JSON document. Any application that decodes attacker-supplied JSON with Protobuf.JSON.decode/3, Protobuf.JSON.decode!/3, or Protobuf.JSON.from_decoded/3 into a schema that contains a self-referential or cyclic message type is affected.
In lib/protobuf/json/decode.ex, the embedded-message clause of decode_singular/3 recurses into internal_from_json_data/3 once per nesting level without incrementing or checking the decoder's depth counter. The depth guard increase_depth_and_maybe_throw/1 covers only the Google.Protobuf.ListValue and Google.Protobuf.Struct clauses, so the recursion_limit option has no effect on user-defined message types. Each nesting level allocates a stack frame and heap objects, and a sufficiently deep document exhausts the memory of the decoding process. Confidentiality and integrity are not affected.
This issue affects protobuf: from 0.8.0 before 0.17.1.
- Record
EUVD-2026-95562- CVSS 4.0
- 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 - Updated
- 2026-11-02
NVD
8.2
Uncontrolled Recursion vulnerability in Protobuf.JSON.Decode in elixir-protobuf protobuf allows an unauthenticated remote attacker to crash the decoding process via a deeply nested JSON document. Any application that decodes attacker-supplied JSON with Protobuf.JSON.decode/3, Protobuf.JSON.decode!/3, or Protobuf.JSON.from_decoded/3 into a schema that contains a self-referential or cyclic message type is affected.
In lib/protobuf/json/decode.ex, the embedded-message clause of decode_singular/3 recurses into internal_from_json_data/3 once per nesting level without incrementing or checking the decoder's depth counter. The depth guard increase_depth_and_maybe_throw/1 covers only the Google.Protobuf.ListValue and Google.Protobuf.Struct clauses, so the recursion_limit option has no effect on user-defined message types. Each nesting level allocates a stack frame and heap objects, and a sufficiently deep document exhausts the memory of the decoding process. Confidentiality and integrity are not affected.
This issue affects protobuf: from 0.8.0 before 0.17.1.
- Record
CVE-2026-104635- CVSS 4.0
- 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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Weakness
- CWE-674
- Updated
- 2026-11-02
OSV
8.2
Uncontrolled recursion in elixir-protobuf/protobuf JSON decoding of self-referential messages
Uncontrolled Recursion vulnerability in Protobuf.JSON.Decode in elixir-protobuf protobuf allows an unauthenticated remote attacker to crash the decoding process via a deeply nested JSON document. Any application that decodes attacker-supplied JSON with Protobuf.JSON.decode/3, Protobuf.JSON.decode!/3, or Protobuf.JSON.from_decoded/3 into a schema that contains a self-referential or cyclic message type is affected.
In lib/protobuf/json/decode.ex, the embedded-message clause of decode_singular/3 recurses into internal_from_json_data/3 once per nesting level without incrementing or checking the decoder's depth counter. The depth guard increase_depth_and_maybe_throw/1 covers only the Google.Protobuf.ListValue and Google.Protobuf.Struct clauses, so the recursion_limit option has no effect on user-defined message types. Each nesting level allocates a stack frame and heap objects, and a sufficiently deep document exhausts the memory of the decoding process. Confidentiality and integrity are not affected.
This issue affects protobuf: from 0.8.0 before 0.17.1.
- Record
CVE-2026-104635- CVSS 4.0
- 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 - Weakness
- CWE-674
- Updated
- 2026-11-02
OSVEEF-CVE-2026-104635
8.2
Uncontrolled recursion in elixir-protobuf/protobuf JSON decoding of self-referential messages
Summary
Uncontrolled Recursion vulnerability in Protobuf.JSON.Decode in elixir-protobuf protobuf allows an unauthenticated remote attacker to crash the decoding process via a deeply nested JSON document. Any application that decodes attacker-supplied JSON with Protobuf.JSON.decode/3, Protobuf.JSON.decode!/3, or Protobuf.JSON.from_decoded/3 into a schema that contains a self-referential or cyclic message type is affected.
In lib/protobuf/json/decode.ex, the embedded-message clause of decode_singular/3 recurses into internal_from_json_data/3 once per nesting level without incrementing or checking the decoder's depth counter. The depth guard increase_depth_and_maybe_throw/1 covers only the Google.Protobuf.ListValue and Google.Protobuf.Struct clauses, so the recursion_limit option has no effect on user-defined message types. Each nesting level allocates a stack frame and heap objects, and a sufficiently deep document exhausts the memory of the decoding process. Confidentiality and integrity are not affected.
This issue affects protobuf: from 0.8.0 before 0.17.1.
Details
1. Entry points. Protobuf.JSON.decode/3, Protobuf.JSON.decode!/3, and Protobuf.JSON.from_decoded/3 in lib/protobuf/json.ex validate options and call Protobuf.JSON.Decode.from_json_data/3, which builds a state map carrying depth: 0 and the recursion_limit (default 100). from_decoded/3 accepts already-parsed data, so the underlying JSON parser never bounds the depth either.
2. Unguarded recursion. For a user-defined message module, internal_from_json_data/3 calls decode_message/4, which calls decode_regular_fields/3 and decode_oneof_fields/3. Each field value passes through decode_value/3 and, for a singular embedded message, reaches the decode_singular/3 clause matching embedded?: true. That clause calls internal_from_json_data/3 with state unchanged, so state.depth stays at 0 at every nesting level. Repeated fields and map values reach the same clause through decode_repeated/3 and decode_map/3.
3. Guard coverage. increase_depth_and_maybe_throw/1 increments depth and throws {:recursion_limit_exceeded, limit} when it exceeds the limit. It is called only from the Google.Protobuf.ListValue and Google.Protobuf.Struct clauses, which the Google.Protobuf.Value clause delegates to. The recursion_limit documentation scopes the option to those wrappers, and no other path checks depth.
4. Result. A self-referential schema such as a Tree message with a Tree child field recurses once per JSON nesting level with no bound. Each level holds a live stack frame and allocates heap objects, so a sufficiently deep document exhausts the memory of the decoding process and crashes it. The BEAM max_heap_size process flag defaults to unlimited, so repeated or concurrent requests can exhaust the memory of the whole node.
Proof of concept
- Define and compile a self-referential proto3 message, for example a
TreeNodemessage with a single embedded fieldchildof typeTreeNode. - Build a JSON document that nests the
childfield several thousand levels deep, for example by wrapping{}in{"child": ...}5,000 times. - Decode it with
Protobuf.JSON.decode(json, TreeNode, recursion_limit: 100). - Observe that no
Protobuf.JSON.DecodeErrorfor an exceeded recursion limit is raised and the decoder walks every level. The same depth in aGoogle.Protobuf.Structpayload raises{:recursion_limit_exceeded, 100}. At larger depths the decoding process consumes hundreds of megabytes and crashes with stack and heap exhaustion.
Impact
An unauthenticated client that can reach an endpoint decoding JSON into a self-referential message type can crash the decoding process through stack and memory exhaustion with a single request. Repeated or concurrent requests can exhaust the memory of the whole node and disrupt co-located workloads.
Workarounds
Reject JSON documents…
- Record
EEF-CVE-2026-104635- CVSS 4.0
- 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 - Weakness
- CWE-674
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-104635
8.2
Uncontrolled Recursion vulnerability in Protobuf.JSON.Decode in elixir-protobuf protobuf allows an unauthenticated remote attacker to crash the decoding process via a deeply nested JSON document. Any application that decodes attacker-supplied JSON with Protobuf.JSON.decode/3, Protobuf.JSON.decode!/3, or Protobuf.JSON.from_decoded/3 into a schema that contains a self-referential or cyclic message type is affected. In lib/protobuf/json/decode.ex, the embedded-message clause of decode_singular/3 recurses into internal_from_json_data/3 once per nesting level without incrementing or checking the decoder's depth counter. The depth guard increase_depth_and_maybe_throw/1 covers only the Google.Protobuf.ListValue and Google.Protobuf.Struct clauses, so the recursion_limit option has no effect on user-defined message types. Each nesting level allocates a stack frame and heap objects, and a sufficiently deep document exhausts the memory of the decoding process. Confidentiality and integrity are not affected. This issue affects protobuf: from 0.8.0 before 0.17.1.
- Record
UBUNTU-CVE-2026-104635- CVSS 4.0
- 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 - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
protobufHex |
0.8.0 up to 0.17.1, plus listed versions 0.10.00.11.00.12.00.13.00.14.0 Show 6 moreShow less0.14.10.15.00.16.00.16.10.17.00.9.0 |
0.17.1 |
History
| When | Changed | Sources |
|---|---|---|
| 2026-11-03 | affected | |
| 2026-11-02 | created | CVE List, EUVD, NVD, OSV |
References
github.com/elixir-protobuf/protobuf/security/advisories/GHSA-m497-c2h9-rvw6
cna.erlef.org/cves/CVE-2026-104635.html
osv.dev/vulnerability/EEF-CVE-2026-104635
github.com/elixir-protobuf/protobuf/commit/b0a1d4eaffaf50012fa71a8e931a47cf252d0370
github.com/elixir-protobuf/protobuf/commit/e9432ad1c4099511905353cebcececa3a1f7c3ff
github.com
Left out here: the rest of 1 source description. The JSON record has them.