Jul 6, 2026·7 min read·37 visits
Unrestricted PackBits decompression in golang.org/x/image/tiff allows unauthenticated remote attackers to trigger denial of service via memory exhaustion using a crafted 2MB TIFF image that decompresses to 745MB.
CVE-2026-46599 (also identified by Go vulnerability alias GO-2026-5032) is a high-severity denial-of-service vulnerability in the Go image repository, specifically within the TIFF decoder's PackBits decompression engine. A lack of resource limits during the parsing of Run-Length Encoded PackBits streams allows an attacker to construct a crafted TIFF image that achieves significant decompression amplification. This flaw enables an unauthenticated remote attacker to exhaust system resources, leading to an Out-of-Memory crash or a prolonged application hang.
The golang.org/x/image/tiff package provides an official decoder for Tagged Image File Format (TIFF) files in the Go programming language ecosystem. Because image decoding is a resource-intensive operation, processing untrusted file inputs exposes applications to potential resource exhaustion attacks. When applications ingest user-provided images to generate thumbnails, store avatars, or perform format conversion, they rely on the decoding library to safely restrict resource consumption.
This vulnerability, designated as CVE-2026-46599, resides specifically in the implementation of the PackBits decompression scheme inside the TIFF decoder. PackBits is a byte-oriented Run-Length Encoding (RLE) standard used to compress image data strips within a TIFF container. The vulnerability falls under the CWE-770 classification (Allocation of Resources Without Limits or Throttling), indicating that the software allocates system memory on behalf of an untrusted source without enforcing an upper bound.
Unlike more complex compression algorithms in the same package that route inputs through safe buffers with size limitations, the PackBits decoder directly processed data blocks without measuring or constraining the output size. The resulting impact is high-severity denial-of-service (DoS) via complete exhaustion of available system memory. Unauthenticated remote attackers can exploit this flaw by delivering a maliciously structured TIFF file to any Go application that decodes TIFF images.
PackBits operates on a simple state machine where each compression run begins with a signed 8-bit header byte, followed by literal or replicated data bytes. A header byte n between 0 and 127 indicates a literal run, meaning the decoder must copy the next n + 1 bytes directly to the destination. A header byte n between -127 and -1 indicates a replicated run, instructing the decoder to duplicate the single subsequent byte -n + 1 times. The value -128 is a no-op.
A replicated run can compress up to 128 bytes of repeated data into just 2 bytes of input (the header byte and the repeated byte). This structure provides a maximum single-run compression ratio of 64x. By chaining multiple replicated runs across multiple strips of a single TIFF file, an attacker can construct a high-ratio compression bomb that requires minimal input data but produces a disproportionate volume of output bytes.
The root cause of this vulnerability lies in the path routing of the main Decode function in tiff/reader.go. While other decompression algorithms such as LZW, Deflate, and CCITT restrict buffer expansion by employing the readBuf utility, the PackBits parser called unpackBits directly with a raw reader. Inside unpackBits in tiff/compress.go, the decompression loop repeatedly appended data to a destination byte slice until the input reader returned io.EOF, neglecting to verify whether the accumulated size of the buffer had exceeded the maximum safe limit configured for a single image strip.
To understand the implementation flaw, we can analyze the vulnerable code path compared to the corrected logic in the official patch. In the unpatched version of unpackBits, the function signature only accepted an io.Reader and returned the raw decompressed byte slice.
// Unpatched version of unpackBits
func unpackBits(r io.Reader) ([]byte, error) {
buf := make([]byte, 128)
dst := make([]byte, 0, 1024)
br, ok := r.(byteReader)
// ... decoding loop reads codes and appends to dst ...
for {
// ... read headers and copy
if code >= 0 {
dst = append(dst, buf[:code+1]...)
} else if code != -128 {
dst = append(dst, buf[:1-code]...)
}
}
}The patch (commit fe8ae458fe5e09e39a635719a8c2ec5393d0e815) mitigates this behavior by adding an explicit upper bound limit (lim int64) to the unpackBits parameter list. During each iteration of the decoding loop, the routine evaluates the length of the destination slice against this threshold.
// Patched version of unpackBits
func unpackBits(r io.Reader, lim int64) ([]byte, error) {
buf := make([]byte, 128)
dst := make([]byte, 0, 1024)
// ... parsing loop
for {
// ... decode literal or replicated runs
if code >= 0 {
dst = append(dst, buf[:code+1]...)
} else if code != -128 {
dst = append(dst, buf[:1-code]...)
}
// Explicit size validation added to prevent memory exhaustion
if int64(len(dst)) > lim {
return nil, FormatError("PackBits: decompressed data too large")
}
}
}Additionally, the calling site in tiff/reader.go was updated to pass blockMaxDataSize as the limit argument. This aligns the PackBits decompression path with the limits previously established for other image compression formats under CVE-2023-29408, ensuring consistent protection across all codecs.
Exploiting this vulnerability does not require any specific target configuration, prior authentication, or complex cryptographic operations. The attack vector is entirely remote and requires only that the target application exposes an endpoint accepting TIFF images for processing.
An attacker begins by creating a TIFF file containing a single large strip compressed with PackBits. The payload consists of repetitive byte sequences that map directly to high-amplification replicated runs (such as repeated headers of 0x81 followed by a null byte). A crafted payload of 2MB can easily expand to 745MB of memory upon decompression. This translates to an amplification factor of over 370x.
When the application receives the file, it calls tiff.Decode(). The library parses the TIFF tags, identifies the PackBits compression scheme (tag value 32773), and hands the file descriptor to the vulnerable unpackBits function. As the engine loops through the compressed runs, it continuously expands the buffer. This triggers excessive physical memory consumption within milliseconds, exhausting available memory, triggering garbage collection thrashing, and forcing the operating system to issue a SIGKILL signal to terminate the application.
The primary security impact of CVE-2026-46599 is a complete denial of service. Because image parsing is often executed synchronously in response to HTTP requests, a single request containing a malicious payload can crash the backend server, terminating all active sessions and transactions processed by that instance.
If the application is configured to automatically restart upon failure, an attacker can repeatedly send the malicious payload to keep the server in a continuous loop of crashing and restarting. This permanently denies access to legitimate users. In cloud environments where container orchestrators automatically spin up new instances, this attack can rapidly inflate hosting costs by driving CPU usage and memory resource limits to their maximum thresholds.
The CVSS v3.1 score for this vulnerability is 7.5 (High), reflecting a network-based, low-complexity vector with high availability impact. No confidentiality or integrity impact is present, as the vulnerability does not allow memory disclosure or arbitrary code execution.
The definitive resolution for CVE-2026-46599 is to update the Go subrepository dependency to a secure release. Developers should upgrade the golang.org/x/image package to version v0.41.0 or higher.
To apply the update, run the following commands in the directory containing the go.mod file of your project:
go get golang.org/x/image@v0.41.0
go mod tidyAfter updating the dependency, you must rebuild and redeploy all application binaries. Because Go compiles dependencies statically into the final executable, simply updating the libraries on the server host without recompiling the application will not apply the security patch.
For systems where immediate updating is not feasible, temporary workarounds can mitigate the risk. Implement a middleware layer that inspects the request body size and blocks files with .tiff or .tif extensions. Alternatively, parse the file headers to verify the magic bytes (0x49492A00 or 0x4D4D002A) and reject all TIFF payloads at the application boundary prior to invoking any image decoding functions.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
golang.org/x/image/tiff Go | < v0.41.0 | v0.41.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-770 (Allocation of Resources Without Limits or Throttling) |
| Attack Vector | Network (AV:N) |
| CVSS Score | 7.5 (High) |
| EPSS Score | 0.00353 |
| EPSS Percentile | 27.35% |
| Exploit Status | No public functional exploit code (None/PoC-only) |
| KEV Status | Not in CISA's Known Exploited Vulnerabilities (KEV) catalog |
The software allocates a resource (memory buffer) on behalf of an untrusted actor without a cap or restriction on the size of the allocation.
CVE-2026-55694 is a chained Information Disclosure and Insecure Direct Object Reference (IDOR) vulnerability in Snipe-IT prior to version 8.6.3. The vulnerability allows authenticated, restricted users to completely bypass randomized file-naming security controls, leak the obfuscated filenames of signed End User License Agreements (EULAs), and subsequently download these confidential documents across tenant boundaries.
Snipe-IT is an IT asset/license management system. Prior to 8.6.3, any activated account can request /maintenances/{id} and read maintenance records for assets in the same company without asset or maintenance permission. app/Http/Controllers/MaintenancesController.php show() renders the record without authorize(), while company-scoped route-model binding only prevents access to other companies. Disclosed fields include asset tags, suppliers, purchase costs, notes, and dates. This issue is fixed in version 8.6.3.
A Stored DOM-based Cross-Site Scripting (DOM XSS) vulnerability exists in Snipe-IT versions prior to 8.6.2. The vulnerability occurs when a stored manufacturer or supplier name is converted to CamelCase and rendered within the 'data-selected-count-id' attribute of a table. Client-side JavaScript retrieves this decoded attribute and performs unsafe string concatenation, passing it directly into jQuery's '.after()' method, enabling authenticated attackers to execute arbitrary JavaScript in the victim's session.
CVE-2026-62673 (also known as CVE-2026-62230 and GHSA-vwg3-w8w3-pc79) is a high-severity security bypass vulnerability in the Grav CMS. It permits unauthenticated remote attackers to circumvent directory and file access policies defined in Apache .htaccess. This flaw allows direct retrieval of sensitive configuration files, system-level credentials, and database equivalents from case-insensitive host filesystems.
A credential disclosure vulnerability in the mcp-searxng NPM package prior to version 1.12.0 allows attackers to recover plain-text SearXNG Basic Authentication credentials. The application exposes these credentials via console logs (stderr), MCP logging notifications, validation error messages, and JSON-RPC error responses. This occurs because the application lacks comprehensive sanitization across diagnostic boundaries when credentials are parsed from the SEARXNG_URL environment variable.
A detailed technical analysis of CVE-2026-61711, an input validation flaw in Moby BuildKit prior to version 0.31.1. The flaw allows unauthorized or custom frontends to construct build execution environments where Seccomp and AppArmor configurations are completely disabled by supplying an invalid protobuf enum index, resulting in an elevated kernel-level attack surface inside the build sandbox.