go-zserio, Unbounded Memory Allocation, CVE-2026-33524 (Critical)

Listen to this Post

The vulnerability exists because the zserio runtime unconditionally trusts size values embedded in maliciously crafted serialized data. When it processes arrays, strings, or bytes (blobs), it first reads the claimed length from the input, then attempts to allocate exactly that amount of memory. An attacker can place an arbitrarily large integer (e.g., 2,147,483,647) in a payload as small as 4-5 bytes. The runtime does not validate this claimed size against the actual remaining data in the stream, nor does it cap the allocation. As a result, the deserializer immediately allocates memory for the requested size, leading to exhaustion of available RAM and an out-of-memory (OOM) condition, which crashes the application. The issue affects the Go implementation (go-zserio) as well as the C++/Java runtimes. The amplification ratio can exceed 200 million times: a 4-byte payload claiming 100 million elements forces a 762 MB allocation. A 5-byte payload claiming the maximum 32-bit signed integer forces an allocation of approximately 16 GB, causing a system crash on 64-bit systems.
Platform: go-zserio
Version: github.com/woven-planet/go-zserio <0.9.1
Vulnerability : Unbounded Memory Allocation
Severity: Critical
date: Apr 24, 2026

Prediction: 2026-05-08

What Undercode Say:

Set safe upper bounds for array and blob allocations:
export ZSERIO_MAX_INITIAL_ARRAY_SIZE=10000
export ZSERIO_MAX_INITIAL_BLOB_SIZE=1048576 1 MiB
Test the OOM behavior on a vulnerable binary:
echo -e '\xff\xff\xff\x7f' | ./vulnerable_parser
// Vulnerable snippet (go-zserio pre-0.9.1):
func (array Array[T, Y]) UnmarshalZserio(reader zserio.Reader) error {
// ...
arraySize := int(u64ReadSize)
// No size validation – directly allocates 'arraySize' elements:
array.RawArray = make([]T, 0, arraySize)
// ...
}

how Exploit:

  1. Craft a malicious payload – encode a `varsize` field with a large value (e.g., `0x7FFFFFFF` for ~2.1GiB elements). The payload can be as small as 4–5 bytes.
  2. Deliver the payload – feed it to any component that deserializes zserio data (e.g., NDS.Live map updates, backend processing pipelines, or supply-chain data files).
  3. Trigger the allocation – when the runtime reads the size and calls make([]T, 0, claimedSize), memory is immediately allocated. No further data is required.
  4. Cause OOM – the allocation exhausts available memory, crashing the process. Repeated exploitation can lead to a Denial of Service (DoS).

Protection from this CVE

  • Apply the official patch – upgrade to `github.com/woven-planet/go-zserio >=0.9.1` (commit 39ef1dec).
  • Set environment limits – define `ZSERIO_MAX_INITIAL_ARRAY_SIZE` and `ZSERIO_MAX_INITIAL_BLOB_SIZE` to safe upper bounds (e.g., 1000 and 100KiB).
  • Validate untrusted input – never accept zserio data from untrusted sources without an external size check.
  • Use TLS for transport – ensure data integrity to detect tampered sizes before deserialization.
  • Implement stream‑size validation – reject any size that exceeds the remaining bytes in the stream.

Impact

  • Denial of Service – low‑overhead payloads (4–5 bytes) crash the application with OOM.
  • Supply‑chain risk – affects NDS (Navigation Data Standard) used by 43 automotive companies (Toyota, BMW, VW, Mercedes‑Benz, etc.).
  • Embedded systems impact – on 32‑bit ECUs, the vulnerability can affect ADAS functionality.
  • Widespread deployment – “zserio serialized data is used in millions of deployments in cars on the road” (Eclipse zserio project).
  • No authentication required – any endpoint that accepts zserio data is exploitable.

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top