docs/security.md lists decompression bombs as a currently unmitigated limitation: a tiny archive can expand to enormous data and exhaust disk or memory during extract. This adds the standard output-budget defense to collapse-core extraction.
Scope
- Total output cap — track bytes written across the whole extraction; abort with a clear error when a limit is exceeded.
- Ratio cap — abort when output/input ratio is implausibly high (bombs run 1000:1+; legit archives rarely exceed ~100:1). Uses the per-entry compressed/uncompressed sizes the formats expose.
- Entry-count cap — abort on archives with an absurd number of entries (the "millions of tiny files" variant).
- Limits should be configurable, with safe defaults.
Implementation notes
- zip / 7z: we already control the per-entry extraction loop (
extract_zip; extract_7z via decompress_with_extract_fn), so wrap each entry reader in a bounded/counting reader (Read::take) and abort mid-stream.
- Enforce on actual bytes read, not the declared header size — a bomb can declare a small size and deliver gigabytes.
- Stream instead of buffering — extraction currently
read_to_ends each entry into memory before writing, so a huge entry exhausts RAM before any disk cap triggers; switch to a streaming copy that counts as it goes. This is the main piece of work.
- tar is a near-non-issue (uncompressed container, ratio ~1:1); only the entry-count / total-size cap is relevant, and we do not support
.tar.gz.
- Not affected: recursive/nested bombs (we only extract one level) and overlapping-entry tricks (a total-bytes cap defends against the effect regardless).
Acceptance criteria
Related: docs/security.md.
docs/security.mdlists decompression bombs as a currently unmitigated limitation: a tiny archive can expand to enormous data and exhaust disk or memory duringextract. This adds the standard output-budget defense tocollapse-coreextraction.Scope
Implementation notes
extract_zip;extract_7zviadecompress_with_extract_fn), so wrap each entry reader in a bounded/counting reader (Read::take) and abort mid-stream.read_to_ends each entry into memory before writing, so a huge entry exhausts RAM before any disk cap triggers; switch to a streaming copy that counts as it goes. This is the main piece of work..tar.gz.Acceptance criteria
tests/core/tests/security.rscover a crafted high-ratio archive and an excessive-entry-count archive.docs/security.mdupdated: move decompression bombs from "known limitations" to a documented measure.Related:
docs/security.md.