VYPR
High severity7.5NVD Advisory· Published Apr 8, 2026· Updated Apr 17, 2026

CVE-2026-40036

CVE-2026-40036

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.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
dfir-unfurlPyPI
< 2026040520260405

Affected products

1
  • cpe:2.3:a:ryandfir:unfurl:*:*:*:*:*:*:*:*
    Range: <2026.04

Patches

1
7cc711a65b10

Merge pull request #243 from obsidianforensics/decompress-limits

https://github.com/RyanDFIR/unfurlRyan BensonApr 3, 2026via ghsa
2 files changed · +31 5
  • unfurl/parsers/parse_compressed.py+8 5 modified
    @@ -40,7 +40,10 @@ def run(unfurl, node):
             return False
     
         if node.data_type == 'zlib':
    -        inflated_str = zlib.decompress(node.value)
    +        try:
    +            inflated_str = utils.safe_decompress(node.value)
    +        except (zlib.error, ValueError):
    +            return
             unfurl.add_to_queue(
                 data_type='zlib-inflate', key=None, value=inflated_str,
                 hover='This data was inflated using zlib',
    @@ -79,9 +82,9 @@ def run(unfurl, node):
             return
     
         try:
    -        inflated_bytes = zlib.decompress(decoded)
    -    except:
    -        # If we can't inflate it, bail on this parser.
    +        inflated_bytes = utils.safe_decompress(decoded)
    +    except (zlib.error, ValueError):
    +        # If we can't inflate it or it exceeds size limit, bail on this parser.
             return
     
         try:
    @@ -93,7 +96,7 @@ def run(unfurl, node):
                     hover='This data was base64-decoded, then zlib inflated',
                     incoming_edge_config=b64_zip_edge)
                 return
    -    except:
    +    except UnicodeDecodeError:
             # If we couldn't decode the inflated bytes as ASCII, that's ok; we'll
             # just show the raw inflated bytes below.
             pass
    
  • unfurl/utils.py+23 0 modified
    @@ -17,6 +17,7 @@
     import ipaddress
     import re
     import textwrap
    +import zlib
     from datetime import datetime
     from typing import Union
     
    @@ -119,3 +120,25 @@ def extract_bits(identifier: int, start: int, end: int) -> int:
     def set_bits(value: int, offset: int, max_size=None) -> int:
         return int(value << offset)
     
    +
    +# Maximum decompressed size (1MB) to prevent zip bomb attacks
    +MAX_DECOMPRESSED_SIZE = 1_000_000
    +
    +
    +def safe_decompress(data: bytes, max_size: int = MAX_DECOMPRESSED_SIZE) -> bytes:
    +    """Decompress zlib or gzip data with a size limit to prevent zip bomb attacks.
    +
    +    Uses wbits=47 (32 + MAX_WBITS) to auto-detect zlib or gzip format.
    +
    +    :param data: Compressed bytes to decompress
    +    :param max_size: Maximum allowed decompressed size in bytes
    +    :return: Decompressed bytes
    +    :raises ValueError: If decompressed data exceeds max_size
    +    :raises zlib.error: If decompression fails
    +    """
    +    decompressor = zlib.decompressobj(wbits=32 + zlib.MAX_WBITS)
    +    result = decompressor.decompress(data, max_size)
    +    if decompressor.unconsumed_tail:
    +        raise ValueError("Decompressed data exceeds size limit")
    +    return result
    +
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.