Skip to content

VNX-409: Improper Handling of Highly Compressed Data (Data Amplification)

Decompression with no bound on the output size: Python zipfile extractall() or per-member extract(), or tarfile extractall(), without a member size check, shutil.unpack_archive, gzip/zlib/bz2/lzma.decompress of request or network data; Node zlib gunzip/inflate/unzip/brotliDecompress without maxOutputLength, request streams piped through createGunzip, adm-zip extractAllTo, and unzipper.Extract or unzipper.Open entries streamed without an uncompressedSize check.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-409
Severity Medium
SARIF level warning
Kind sast
Languages JavaScript / TypeScript, Python
CWE CWE-409
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:M/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C
Tags data-amplification cwe-409
Source internal/sast/rules/vnx-409.rego

Overview

VNX-409 maps to CWE-409: Improper Handling of Highly Compressed Data (Data Amplification). The rule reports decompression whose output size is not bounded, so a small compressed input (a zip or gzip bomb) expands until memory or disk runs out.

Why This Matters

Compression ratios of 1000:1 are easy to build, and nested archives reach far more. A server that decompresses an upload or a request body without capping the output lets one small request exhaust memory or fill the disk.

What Gets Flagged

with zipfile.ZipFile(upload) as zf:
    zf.extractall(UPLOAD_DIR)                 # FLAGGED: no file_size check in the file

payload = request.get_data()
raw = gzip.decompress(payload)                # FLAGGED: request body, no output limit

shutil.unpack_archive(saved_path, plugin_dir) # FLAGGED
const body = zlib.gunzipSync(req.body);              // FLAGGED: no maxOutputLength
req.pipe(zlib.createGunzip()).pipe(out);             // FLAGGED
zip.extractAllTo(dir, true);                         // FLAGGED (adm-zip)

Not flagged: zlib.gunzipSync(buf, { maxOutputLength: 1 << 20 }), zlib.decompressobj().decompress(data, MAX), an archive whose members’ file_size is summed before extraction, Python decompression of local or constant data, compression calls (gzipSync, createGzip), test files, comments and strings.

Remediation

  1. Node: pass { maxOutputLength: <limit> } to every zlib convenience method; count bytes in a Transform for streams.
  2. Python: sum info.file_size over infolist() and reject archives over a limit; use zlib.decompressobj().decompress(data, max_length) for streams.
  3. For confirmed false positives, add a # vulnetix-ignore: VNX-409 comment on the line.

References

Suppressing this rule

Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):

# nosec vnx-409
// nosec vnx-409

Or record an ignore rule: vulnetix ignore add --rule vnx-409 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-409.rego, cli/internal/sast/docs/vnx-409.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.