May 7, 2026·7 min read·28 visits
Unbounded memory allocation in rust-zserio allows remote attackers to trigger an Out-of-Memory crash by providing malformed bitstreams with massive array lengths.
A critical vulnerability exists in the rust-zserio crate regarding how auto-generated deserialization routines handle variable-length structures. By supplying a maliciously crafted Zserio bitstream with an artificially inflated size header, an attacker can force the application to request massive memory allocations, resulting in an Out-of-Memory (OOM) panic and process termination.
The rust-zserio crate provides native Rust bindings and code generation capabilities for the Zserio serialization protocol. Zserio is designed for memory-efficient and schema-driven data encoding, frequently employed in embedded systems and network communications. The generated decoders handle bit-level parsing of serialized structures based on predefined schemas.
A critical vulnerability, tracked as GHSA-FPF5-4JW8-67X8, exists in the auto-generated deserialization routines of the rust-zserio crate. The flaw is classified as CWE-770: Allocation of Resources Without Limits or Throttling. It manifests during the decoding of variable-length arrays, strings, and byte sequences from untrusted bitstreams.
The underlying issue stems from a structural misalignment between the declarative length of incoming data and the actual bytes present in the payload. The vulnerable decoders implicitly trust the length headers embedded within the serialized data. Consequently, the application attempts an immediate, upfront memory allocation equal to the declared length before validating the remainder of the bitstream.
The root cause of this vulnerability lies in the implementation of array and sequence instantiation within the generated Rust decoder code. Specifically, the crates/zserio-rs-build/src/internal/generator/decode.rs component dictates how the decoder processes variable-length fields. When encountering an array, the decoder first reads the varsize integer prefix.
The varsize header dictates the number of elements contained in the subsequent data stream. In the vulnerable implementation, the decoder utilizes the vec![initial_value; array_length] macro to initialize the entire sequence simultaneously. This macro triggers the Rust memory allocator to request a continuous block of heap memory capable of holding the specified number of elements.
Because the varsize value is read directly from the untrusted network payload, an attacker maintains complete control over the array_length parameter. The decoder performs no bounds checking against the physical size of the remaining bitstream or the available system memory. If the requested allocation size exceeds the available heap space, the Rust runtime triggers an unrecoverable panic, resulting in immediate process termination.
This behavior violates the principle of incremental resource allocation during untrusted data parsing. By treating the unverified length prefix as an authoritative allocation directive, the system creates a direct pathway for resource exhaustion. The vulnerability requires only a few bytes of malicious input to force gigabytes of memory allocation requests.
An examination of the codebase reveals the mechanical nature of the vulnerability. In versions prior to the patch, the code generator emitted deserialization logic that performed bulk memory initialization. The unpatched code path explicitly requested full allocation via the vec! macro based purely on the parsed header size.
// Vulnerable implementation in generated decode.rs
function.line(format!(
"{} = vec![initial_value; {}_array_length];",
rvalue_field_name, field_details.field_name,
));This single line of generated code forces the Rust standard library to attempt a massive contiguous heap allocation. If array_length is crafted to be 0x7FFFFFFF (the maximum value for a 32-bit signed integer) and the element size is 4 bytes, the process immediately requests 8 gigabytes of memory.
The patch implemented in commit 57f5fb4a2a8611d58dbcc1a9221349206dd99c3c mitigates this issue by fundamentally altering the allocation strategy. The updated generator now employs a chunked reservation system and an incremental growth model. The system limits the initial capacity reservation to a configurable threshold, defined by zserio::get_array_alloc_chunk().
// Patched implementation utilizing chunked reservation
data.reserve(array_length.min(ARRAY_ALLOC_CHUNK.load(Ordering::Relaxed)));
// ... followed by a push-based loop that validates available stream data
for _ in 0..array_length {
data.push(read_element(reader)?);
}By utilizing data.push() within a loop, the decoder reads and instantiates elements one by one. If the bitstream terminates prematurely, the read_element function returns an error, safely aborting the decoding process before any dangerous memory growth occurs. Similar bounds checking was implemented for read_string and read_bytes.
Exploitation of GHSA-FPF5-4JW8-67X8 is straightforward and requires minimal bandwidth. The attacker must possess the ability to deliver a serialized Zserio payload to an endpoint utilizing the vulnerable generated code. No authentication or complex state manipulation is necessary to trigger the condition.
The exploit methodology begins with the construction of a malformed Zserio object. The attacker crafts a payload where a target array, string, or byte blob field begins with a mathematically maximized varsize header. The integer representation is manipulated to indicate a sequence length that guarantees a fatal memory allocation failure.
Immediately following the manipulated header, the attacker truncates the payload or provides minimal arbitrary data. The total size of the transmitted exploit packet is typically less than twenty bytes. The efficiency of this attack vector makes it highly effective for distributed denial-of-service (DDoS) campaigns, as the cost to the attacker is negligible.
Upon reception, the target application enters the deserialization routine. It extracts the inflated length parameter and issues the memory allocation request. The operating system denies the excessive allocation, the Rust runtime panics due to the Out-of-Memory condition, and the hosting process crashes unconditionally.
The primary impact of this vulnerability is a complete Denial of Service (DoS). When the target application encounters the malformed input, the resulting memory exhaustion crash immediately terminates the process. All concurrent operations, active connections, and internal states managed by the process are destroyed.
For systems deploying rust-zserio in network-facing roles, such as telemetry aggregators or IPC message brokers, this vulnerability poses a severe reliability threat. Continuous transmission of the exploit payload will trap the service in a perpetual crash-loop. High availability architectures will struggle to maintain uptime, as instances are terminated as rapidly as they can be restarted.
The vulnerability exhibits a highly asymmetric resource cost. The computational and bandwidth requirements for the attacker are virtually zero, while the operational cost to the defender is complete service disruption. This dynamic is characteristic of CWE-770 and underscores the necessity of strict resource boundaries when processing untrusted input.
The diagram models the failure path. Regardless of whether the operating system strictly denies the allocation or attempts to swap memory, the outcome is detrimental to the host system.
The definitive remediation for GHSA-FPF5-4JW8-67X8 is upgrading the rust-zserio dependency to the latest version encompassing commit 57f5fb4a2a8611d58dbcc1a9221349206dd99c3c. Following the dependency update, developers must regenerate all Zserio deserialization code to apply the patched allocation logic.
The patched version introduces configurable chunk allocation limits to balance performance and safety. Developers can tune the initial memory allocation threshold utilizing the zserio::set_array_alloc_chunk(n: usize) function. The default value of 1,000 elements provides a sensible baseline, preventing bulk allocation while maintaining efficient parsing for legitimate structures.
If immediate deployment of the patched library is not feasible, mitigation options are limited. Network-level controls, such as Web Application Firewalls (WAFs), cannot reliably inspect binary Zserio bitstreams due to the lack of clear-text signatures and the complex nature of the schema definitions. Therefore, remediation must occur at the application layer.
Organizations utilizing rust-zserio should audit their network exposure and restrict access to deserialization endpoints. Implementing strict mutual TLS (mTLS) authentication or network segmentation can drastically reduce the attack surface, limiting exploitation capabilities to trusted internal entities until the patch is fully integrated.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
rust-zserio Danaozhong | < 57f5fb4a2a8611d58dbcc1a9221349206dd99c3c | 57f5fb4a2a8611d58dbcc1a9221349206dd99c3c |
| Attribute | Detail |
|---|---|
| CWE | CWE-770 |
| Attack Vector | Network (Malicious Payload) |
| Impact | Denial of Service (DoS) |
| Exploit Status | Proof of Concept (PoC) Available |
| Authentication Required | None |
| Remediation | Code Generator Update |
The software allocates memory or other resources based on an untrusted size value, without enforcing a safe upper limit.
CVE-2026-16729 (GHSA-v3r7-h72x-cjcm) is a medium-severity cookie attribute injection vulnerability in Undici's web-compliant cookie utility module. Due to insufficient validation of domain parameters and raw attributes in the unparsed options array, arbitrary attributes like SameSite, HttpOnly, and Secure can be injected. This allows attackers to bypass CSRF protections, strip security flags, or override intended cookie behaviors when applications pass user-controlled values to these properties.
An interpretation conflict (CWE-436) in the cache interceptor of the undici HTTP client for Node.js causes whitespace-padded Cache-Control directives to be parsed incorrectly, leading to shared cache pollution and the unauthorized disclosure of sensitive, private, or authenticated user information (CWE-524).
CVE-2026-15157 details an improper neutralization of CRLF sequences ('CRLF Injection') within undici, a widely used Node.js HTTP/1.1 client. The vulnerability is triggered when processing request bodies that exhibit a duck-typed blob-like interface. When an application accepts untrusted data and assigns it to the .type property of such an object without setting an explicit Content-Type on the request, undici appends the value directly to the outgoing headers array without validating it against control characters. This allows remote attackers to inject carriage return and line feed sequences, culminating in arbitrary header injection, HTTP response splitting, or HTTP request smuggling.
A trust-boundary bypass and Server-Side Request Forgery (SSRF) vulnerability exists in the ip-address library versions 10.1.1 through 10.2.0 due to structural input misclassification. The library fails to resolve and normalize transition IP notations, such as IPv4-mapped IPv6 (::ffff:0:0/96) and NAT64 (64:ff9b::/96) addresses, to their embedded IPv4 representations prior to evaluation. Consequently, standard security validation checks (e.g., isLoopback, isLinkLocal, isULA) return false for these addresses. This allows remote attackers to bypass application-level IP address filters, gaining unauthorized access to internal resources, cloud metadata interfaces, and local services on dual-stack hosts or environments utilizing NAT64 gateways.
A critical authentication bypass vulnerability (CVE-2026-18574) in Check Point Security Management and Multi-Domain Security Management (MDS) Servers allows unauthenticated remote attackers to execute arbitrary system commands with administrative privileges. The flaw stems from an alternate path authentication bypass (CWE-288) in the management interface daemons.
An input validation vulnerability in the npm package `ip-address` allows unauthenticated remote attackers to bypass Server-Side Request Forgery (SSRF) protections by appending a `/0` CIDR suffix to IP address strings. This causes the library's classification helper functions to incorrectly identify internal addresses as public, external addresses, while normalization helpers resolve the address back to its internal form during network connection establishment.