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.
| Package | Affected versions | Patched versions |
|---|---|---|
dfir-unfurlPyPI | < 20260405 | 20260405 |
Affected products
1Patches
17cc711a65b10Merge pull request #243 from obsidianforensics/decompress-limits
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- github.com/obsidianforensics/unfurl/security/advisories/GHSA-h5qv-qjv4-pc5mnvdExploitVendor AdvisoryWEB
- github.com/advisories/GHSA-h5qv-qjv4-pc5mghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-40036ghsaADVISORY
- www.vulncheck.com/advisories/dfir-unfurl-denial-of-service-via-unbounded-zlib-decompressionnvdThird Party AdvisoryWEB
- github.com/RyanDFIR/unfurl/commit/7cc711a65b106742a21080b755f81c17b5725aa8ghsaWEB
- github.com/RyanDFIR/unfurl/pull/243ghsaWEB
- github.com/RyanDFIR/unfurl/releases/tag/v2026.04ghsaWEB
- github.com/obsidianforensics/unfurl/releases/tag/v2026.04nvdRelease Notes
News mentions
0No linked articles in our index yet.