CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-35480
6.2

CVE-2026-35480: Unbounded Memory Allocation and Denial of Service in go-ipld-prime DAG-CBOR Decoder

Alon Barad
Alon Barad
Software Engineer

Apr 7, 2026·6 min read·4 visits

PoC Available

Executive Summary (TL;DR)

A flaw in the go-ipld-prime DAG-CBOR decoder allows attackers to trigger Out-of-Memory (OOM) crashes via small payloads with large declared map or list lengths. The vulnerability is fixed in version 0.22.0.

The go-ipld-prime library prior to version 0.22.0 suffers from a resource exhaustion vulnerability in its DAG-CBOR decoding implementation. Maliciously crafted CBOR payloads containing artificially large declared collection sizes bypass early budget checks, triggering massive upfront memory allocations that result in immediate application crashes.

Vulnerability Overview

The go-ipld-prime library provides an implementation of the InterPlanetary Linked Data (IPLD) specification, primarily utilized in decentralized and distributed systems for data model representation. A critical component of this library is the DAG-CBOR decoder, which translates concise binary object representation payloads into Go data structures. The decoding process must handle untrusted, externally supplied input streams while managing system resources.

Prior to version 0.22.0, the DAG-CBOR decoder failed to properly constrain memory allocation operations derived from user-controlled input lengths. This behavior corresponds to CWE-770 (Allocation of Resources Without Limits or Throttling). The vulnerability manifests when the decoder processes Major Type 4 (Arrays) or Major Type 5 (Maps) CBOR headers, which explicitly declare the number of upcoming elements in the collection.

Applications utilizing go-ipld-prime to parse untrusted DAG-CBOR payloads are susceptible to resource exhaustion attacks. An adversary can submit a minimal payload that claims a massive element count, forcing the Go runtime to attempt an allocation exceeding available system memory. The resulting Out-of-Memory (OOM) panic causes immediate application termination, resulting in a high-impact Denial of Service (DoS) condition.

Root Cause Analysis

The vulnerability originates from a fundamental disconnect between the declared length in a CBOR header and the actual bytes required to represent that length in the payload stream. In the CBOR specification, a 64-bit integer specifying billions of elements requires a maximum of 9 bytes on the wire. The decoder read this length integer and directly used it as a preallocation hint for Go's internal slice and map creation functions.

When creating Go slices or maps, the runtime allocates a contiguous block of backing memory based on the requested capacity. The vulnerable implementation executed make([]datamodel.Node, length) or equivalent map instantiations immediately after parsing the header. This eager allocation strategy intended to optimize performance by minimizing future reallocation overhead as elements were decoded.

While go-ipld-prime implemented an allocation budget system to prevent resource exhaustion, the validation logic contained a critical sequencing flaw. The decoder only decremented the budget counter as individual elements were successfully parsed and validated. Because the massive preallocation occurred before any child elements were processed, the budget system was completely bypassed during the initial memory request.

Code Analysis

An examination of the decoding sequence highlights the structural flaw in early versions. When the decoder identified a map or list, it extracted the length field and passed it directly to the node builder. The runtime then attempted to fulfill the request, ignoring the established resource limits.

The remediation introduced in commit e43bf4a27055fe8d895671a731ee5041e2d983a9 implements a dual-layer defense mechanism within codec/dagcbor/unmarshal.go. The first layer integrates the existing budget system directly into the preallocation phase. The decoder now subtracts the declared length from the remaining allocation budget upfront, returning an ErrAllocationBudgetExceeded error if the request exceeds the limits.

// Early budget validation
if *budget-allocLen < 0 {
    return ErrAllocationBudgetExceeded
}
 
// Preallocation capping layer
if allocLen > options.maxPrealloc() {
    allocLen = options.maxPrealloc()
}
 
// Safe initialization
ma, err := na.BeginMap(allocLen)

The second defensive layer introduces MaxCollectionPrealloc, which defaults to 1024 entries. Regardless of the declared payload length, the initial memory allocation hint passed to the Go runtime is capped at this maximum value. Valid structures containing more than 1024 elements continue to decode correctly, as Go maps and slices will dynamically grow, but the memory consumption is strictly tied to validated, physical bytes received over the wire.

Exploitation and Attack Methodology

Exploitation requires no authentication and relies entirely on delivering a syntactically valid but maliciously structured CBOR sequence to a target endpoint. The attacker constructs a payload consisting of a single Major Type 4 or 5 header, explicitly declaring a 32-bit or 64-bit length. The remainder of the payload can be omitted or truncated.

The attack efficiency scales dramatically through structural nesting. An attacker can construct a list containing a list, repeating this pattern multiple times. Each nested level triggers its own unconstrained preallocation while consuming only a single unit of budget from the parent collection. This structural amplification allows a payload of less than 100 bytes to demand gigabytes of memory allocation.

The following logical proof-of-concept demonstrates the payload generation mechanism required to trigger the vulnerability. The code generates a single map header with a declared length of twenty million elements.

// Conceptual payload generator for CVE-2026-35480
func generateMaliciousCbor() []byte {
    var buf bytes.Buffer
    // 0xBA indicates a Map (Major type 5) with a 32-bit length to follow
    buf.WriteByte(0xBA) 
    // Requesting 20,000,000 preallocated elements
    binary.Write(&buf, binary.BigEndian, uint32(20_000_000)) 
    return buf.Bytes()
}

Impact Assessment

The direct consequence of this vulnerability is an unrecoverable application crash. Go runtimes handle out-of-memory states by terminating the process with a fatal panic that cannot be intercepted by standard recover() routines. An attacker can repeatedly send the malicious payload, maintaining a sustained Denial of Service condition against the target infrastructure.

The severity of the impact varies based on the decoding methodology employed by the application. Schema-free decoding utilizing basicnode.Prototype.Any represents the highest risk profile, as it permits arbitrary structural nesting without constraint. Applications utilizing schema-bound decoding mitigate nested amplification attacks by restricting the depth and structure to a predefined layout, but remain vulnerable to single-level preallocation exhaustion if large collections are permitted.

The CVSS v3.1 score for this vulnerability is 6.2 (Medium). The official vector assigns an Attack Vector of Local (AV:L), which typically implies local access to the execution environment. However, since DAG-CBOR is predominantly used as a serialization format for network communications, network-based exploitation is highly probable in standard deployment architectures.

Remediation and Mitigation Guidance

The primary and most effective remediation is updating the go-ipld-prime dependency to version 0.22.0 or later. This release fundamentally alters the memory allocation behavior, ensuring that memory consumption scales linearly with actual parsed data rather than attacker-controlled metadata flags.

In environments where immediate dependency updating is unfeasible, mitigation options are severely limited. Network layer filtering is generally ineffective, as analyzing serialized CBOR structures requires deep packet inspection capabilities that understand the DAG-CBOR format. Web Application Firewalls (WAFs) cannot easily differentiate between a legitimate large map header and a malicious one without maintaining stateful payload analysis.

Developers should verify their software supply chain and execute dependency scanning tools to identify transitive dependencies that may rely on vulnerable versions of go-ipld-prime. Following the update, no configuration changes are required to activate the protection, as the 1024-element preallocation cap is enabled by default in the new unmarshal options.

Official Patches

IPLDOfficial Release v0.22.0

Fix Analysis (1)

Technical Appendix

CVSS Score
6.2/ 10
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Affected Systems

go-ipld-prime DAG-CBOR Decoder

Affected Versions Detail

Product
Affected Versions
Fixed Version
go-ipld-prime
IPLD
< 0.22.00.22.0
AttributeDetail
CWE IDCWE-770
Attack VectorLocal / Network
CVSS Score6.2
Exploit StatusProof of Concept (Unit Tests)
CISA KEVNot Listed
ImpactHigh Availability Impact (DoS)

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-770
Allocation of Resources Without Limits or Throttling

Allocation of Resources Without Limits or Throttling

Known Exploits & Detection

Patch Unit TestsUnit tests verifying allocation cap behavior provide a logical structure for reproduction.

Vulnerability Timeline

Fix commit e43bf4a27055fe8d895671a731ee5041e2d983a9 pushed to repository
2026-02-16
GitHub Advisory GHSA-378j-3jfj-8r9f published
2026-04-06
CVE-2026-35480 officially published by MITRE/CNA
2026-04-07

References & Sources

  • [1]GHSA-378j-3jfj-8r9f Advisory
  • [2]go-ipld-prime Security Advisory
  • [3]Fix Commit e43bf4a27055fe8d895671a731ee5041e2d983a9
  • [4]CVE-2026-35480 Record
  • [5]go-ipld-prime v0.22.0 Release Notes

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.