Apr 21, 2026·7 min read·15 visits
Unbounded io.Copy operations in OpenBao's OCI plugin extraction allow decompression bombs to exhaust host disk space. The flaw was remediated in version 2.5.3 by implementing io.LimitReader and strict extraction size validations.
OpenBao versions prior to 2.5.3 are vulnerable to a resource exhaustion denial-of-service (DoS) flaw due to unbounded disk writes during OCI plugin extraction. A crafted container image served from a compromised registry acts as a decompression bomb, exhausting host disk space when OpenBao streams the data directly to disk without enforcing size limits.
OpenBao utilizes an Open Container Initiative (OCI) downloader mechanism to retrieve and extract plugins from container image registries. The affected component, residing in the helper/pluginutil/oci/downloader.go module, is responsible for processing compressed image layers and writing the plugin binaries to the local filesystem cache. This subsystem handles untrusted data streams when processing images originating from remote registries.
The vulnerability manifests as an uncontrolled resource consumption flaw (CWE-400) during the extraction phase of the plugin download lifecycle. OpenBao reads the compressed GZIP stream from the container layer and writes the decompressed payload to disk without enforcing maximum allocation thresholds. Processing a maliciously crafted, highly compressed archive results in the rapid depletion of available storage capacity on the host system.
The attack surface is contingent upon the administrative configuration of the OpenBao instance. To exploit this flaw, an adversary must possess the ability to serve a malicious container image from an OCI registry that the target OpenBao instance is configured to trust. The vulnerability triggers automatically upon the initiation of a plugin download operation, requiring no further interaction or authentication from the attacker.
The root cause of CVE-2026-39396 lies in the unsafe application of the standard library io.Copy function within the ExtractPluginFromImage() routine. The function maps a decompressed tar.Reader stream directly to a local file handle. The implementation relies entirely on the internal bounds of the source stream to determine the termination of the write operation.
In Go, the io.Copy function operates by continuously transferring bytes from the source io.Reader to the destination io.Writer until it encounters an EOF marker. When the source is a GZIP-compressed layer containing a decompression bomb, the stream yields an arbitrary volume of null bytes or repeating patterns. The function persistently writes these bytes to the disk, bypassing any memory-based constraints because the data streams directly to the file system block by block.
OpenBao implements an integrity verification mechanism by calculating the SHA256 hash of the extracted plugin binary. However, the cryptographic validation occurs strictly after the io.Copy operation completes. The system writes the entire decompressed payload to the filesystem before inspecting the hash, rendering the validation check ineffective against resource exhaustion attacks that compromise availability during the write phase.
Prior to version 2.5.3, the plugin extraction logic directly fed the unfiltered tar.Reader to the destination file. The application trusted the dimensions of the incoming stream, ignoring the discrepancy between the compressed payload size over the network and its decompressed footprint on disk. The absence of a bounding mechanism left the filesystem exposed to unbounded write operations.
The remediation introduced in commit af576af5322c6552a017ad10fd76aa4f40fd021e implements a multi-layered defense strategy. The developers introduced a configurable hard limit via plugin_download_max_size, enforcing an upper bound of 512 MiB by default. Before initiating any extraction, the system utilizes the shirou/gopsutil library to interrogate the underlying filesystem, ensuring the available disk capacity exceeds the size declared in the Tar archive header.
The core cryptographic mitigation involves restricting the reader itself using io.LimitReader. By wrapping the source stream with io.LimitReader(tarReader, header.Size+1), the standard library forcibly truncates the input if the stream yields more bytes than explicitly declared. Following the bounded read, a strict post-extraction check verifies that the total bytes written precisely matches the header declaration, failing the operation on any deviation.
// Post-patch extraction logic
if header.Size > d.maxPluginSize() { // 1. Max size configuration check
return fmt.Errorf("plugin binary size of %d MiB exceeds allowed size of %d MiB", header.Size/1024/1024, d.maxPluginSize()/1024/1024)
}
diskUsage, err := disk.Usage(filepath.Dir(targetPath))
if diskUsage.Free < uint64(header.Size) { // 2. Capacity validation
return fmt.Errorf("not enough space left on disk to download plugin")
}
// 3. Bounded streaming to prevent bomb expansion
limitReader := io.LimitReader(tarReader, header.Size+1)
n, copyErr := io.Copy(outFile, limitReader)
if n != header.Size { // 4. Strict byte count validation
err = fmt.Errorf("file size was different than reported in tar header")
}Constructing the payload requires the attacker to generate a standard zip bomb, tailored for the GZIP compression algorithm utilized by OCI containers. The adversary synthesizes a massive file consisting entirely of highly compressible sequences, such as consecutive null bytes, achieving extreme compression ratios. A payload of a few megabytes compresses down from a multi-gigabyte virtual footprint.
The delivery mechanism leverages the standard OCI distribution specification. The attacker packages the zip bomb as an independent layer within a container image and pushes the composite artifact to a target registry. The adversary must manipulate the registry routing or compromise existing credentials to ensure the OpenBao instance resolves the attacker-controlled image during a plugin fetch request.
Triggering the exploit sequence relies on the initiation of a plugin download. When an administrator or a scheduled system operation requests the malicious plugin, OpenBao retrieves the compressed layer. As the application processes the layer, the io.Copy routine unwinds the highly compressed payload, rapidly consuming inodes and storage blocks until the filesystem reaches 100% utilization.
Successful exploitation of this vulnerability results in a localized Denial of Service condition on the host system running the OpenBao instance. Exhausting the underlying disk volume prevents OpenBao from writing operational telemetry, storing audit logs, or persisting new secret configurations. Other services sharing the same storage partition will simultaneously experience critical operational failures due to the lack of writable blocks.
The CVSS v3.1 vector evaluates to CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:N/A:L with a base score of 3.1. The availability impact is categorized as low because the OpenBao application process does not inherently crash or terminate; instead, its functional capacity is severely degraded by the environmental constraints. Confidentiality and integrity metrics remain unaffected, as the vulnerability does not expose sensitive memory or allow arbitrary logic execution.
The attack complexity is elevated by the stringent prerequisite of OCI registry control. An attacker cannot simply transmit the malicious payload directly to an OpenBao listener; they must pivot through a configured registry. This architectural constraint significantly mitigates the probability of widespread automated exploitation, aligning with the low EPSS percentile score of 9.66.
The primary remediation strategy requires upgrading all OpenBao deployments to version 2.5.3 or subsequent releases. The patch introduces the necessary bounding logic and the io.LimitReader wrapper that systemically prevents the decompression stream from exceeding declared thresholds, neutralizing the zip bomb attack vector at the standard library level.
Administrators operating patched versions must proactively define the plugin_download_max_size parameter within their server configuration files. Setting this threshold to a pragmatic value ensures that even legitimately oversized, uncompressed plugins do not inadvertently monopolize system storage. Security teams must restrict OpenBao to interact exclusively with trusted, internally managed OCI registries to eliminate the untrusted payload delivery channel entirely.
Detection telemetry should focus on disk utilization metrics and specific application error signatures. Infrastructure monitoring tools must alert operators to sudden, steep accelerations in disk consumption on the volumes mounting the OpenBao .oci-cache directory. Log aggregators should parse OpenBao output streams for explicit warning strings, specifically identifying phrases such as "not enough space left on disk to download plugin" and "file size was different than reported in tar header".
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:N/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
OpenBao OpenBao | < 2.5.3 | 2.5.3 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400 / CWE-770 |
| Attack Vector | Network (Via Registry) |
| CVSS Score | 3.1 (Low) |
| EPSS Score | 0.00033 |
| Impact | Denial of Service (Disk Exhaustion) |
| Exploit Status | Proof of Concept |
| KEV Status | Not Listed |
The software does not properly control the allocation and maintenance of a limited resource, thereby enabling an attacker to influence the amount of resources consumed.
An analysis of four critical vulnerabilities in the skillctl Rust crate (versions 0.1.0 and 0.1.1) that allow arbitrary file exfiltration and directory deletion.
A CSV Formula Injection vulnerability (CWE-1236) exists in the Spree headless eCommerce platform within the customer export functionality. An unauthenticated attacker can register a customer profile containing malicious formula sequences in fields like the first name or last name. When an administrator exports the customer data to a CSV file and opens it in a spreadsheet application, the spreadsheet engine can interpret and execute these formulas, potentially leading to remote command execution on the administrator's workstation or out-of-band data exfiltration.
A Stored Cross-Site Scripting (XSS) vulnerability exists in WWBN AVideo versions up to and including 29.0. Unsanitized category descriptions are stored in the database and subsequently rendered as raw HTML in the Gallery view plugin, allowing low-privileged authenticated users to execute arbitrary JavaScript in the browsers of visiting users.
A critical supply chain compromise was identified in the Node.js package @cap-js/openapi at version 1.4.1. An attacker gained unauthorized publishing access to the npm registry and distributed a backdoored release that harvests sensitive developer credentials, environment variables, and SSH keys. The malicious code then exfiltrates the collected data to external actor-controlled servers.
An authenticated wallet credit bypass vulnerability exists in WWBN AVideo version 29.0 and earlier. The AuthorizeNet plugin includes an unfinished mockup endpoint, processPayment.json.php, which lacks actual transaction verification and hardcodes success. This allows any authenticated user to credit their wallet with arbitrary balances without making any payments.
An unauthenticated stored DOM-based Cross-Site Scripting (DOM XSS) vulnerability in the YPTSocket plugin of WWBN AVideo (formerly YouPHPTube) allows remote attackers to execute arbitrary JavaScript within the session context of administrative users. Unsanitized metadata parameters supplied during the WebSocket handshake are persisted in an SQLite database and broadcast to connected users. The frontend application processes these parameters through an unsafe jQuery append sink, leading to silent, high-impact administrative context compromise.