Apr 7, 2026·6 min read·24 visits
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.
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.
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.
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 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()
}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.
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.
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
go-ipld-prime IPLD | < 0.22.0 | 0.22.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-770 |
| Attack Vector | Local / Network |
| CVSS Score | 6.2 |
| Exploit Status | Proof of Concept (Unit Tests) |
| CISA KEV | Not Listed |
| Impact | High Availability Impact (DoS) |
Allocation of Resources Without Limits or Throttling
A critical stored Cross-Site Scripting (XSS) vulnerability was identified in Froxlor server administration software panel before version 2.3.8. Authenticated customers with DNS editor privileges can inject malicious JavaScript into DNS TXT records. Because the application processes these values via a raw formatting callback without context-aware HTML entity encoding, the payload executes in the security context of administrative users who view the affected domain's DNS zones.
An authenticated administrator with privileges to manage admin accounts (such as change_serversettings) can execute arbitrary SQL commands via a second-order SQL injection vulnerability. The flaw resides in Froxlor's administrative API endpoints, specifically during the handling of IP address mapping parameters which are stored as serialized arrays and later interpolated without sanitization into active database queries. This vulnerability allows high-privileged administrative attackers to compromise the database. By injecting a payload into administrative profile metadata, an attacker can extract sensitive credentials, manipulate backend settings, or potentially disrupt database integrity. The vulnerability affects all versions of Froxlor prior to 2.3.8.
CVE-2026-54543 is a DNS Resource Record (RR) Injection vulnerability in Froxlor, an open-source server administration control panel. Prior to version 2.3.8, the DomainZones.add API command failed to perform strict sanitization and validation on the user-controlled record (label) and type parameters before serializing them into BIND-compatible zone files. An authenticated customer with DNS zone management permissions can inject control characters, breaking out of the original record context to define unauthorized resource records within managed zones.
CVE-2026-42533 is a critical security vulnerability discovered in NGINX Open Source, NGINX Plus, NGINX Ingress Controller, and related products, referred to as the 'Two-Pass Capture-Clobbering' bug. The flaw is situated within NGINX's internal evaluation engine when handling complex variables, exposing a heap-based buffer overflow and information leak when a configuration chains regular expression-based map directives with numbered capture groups. An unauthenticated remote attacker can exploit this weakness by transmitting crafted HTTP requests to trigger remote code execution or defeat ASLR.
Froxlor prior to version 2.3.8 contains a high-severity architectural flaw where the standalone lib/ajax.php entry point bypasses the centralized request validation in lib/init.php. Unauthenticated remote attackers can leverage Cross-Site Request Forgery (CSRF) to induce authenticated administrators to submit forged requests that modify API key whitelists and expiration dates, potentially yielding persistent, out-of-band administrative control.
An insecure data retrieval flaw in the Froxlor server administration panel API allows authenticated remote attackers to retrieve unredacted bcrypt password hashes and Base32-encoded Time-Based One-Time Password (TOTP) seeds. Affected endpoints include several 'get' and 'listing' handlers for customers, administrators, and FTP accounts. Utilizing these leaked parameters, attackers can crack the password hashes offline and concurrently generate valid second-factor authentication codes to completely bypass access controls.