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.
| 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
- Node: pass
{ maxOutputLength: <limit> }to every zlib convenience method; count bytes in a Transform for streams. - Python: sum
info.file_sizeoverinfolist()and reject archives over a limit; usezlib.decompressobj().decompress(data, max_length)for streams. - For confirmed false positives, add a
# vulnetix-ignore: VNX-409comment on the line.
References
- CWE-409: Improper Handling of Highly Compressed Data (Data Amplification)
- Node.js zlib: maxOutputLength
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.