Skip to content

core: guard extraction against decompression bombs (size/ratio/count limits) #7

Description

@otsobide

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

  • Extraction aborts cleanly (no partial escape, clear error) when the size/ratio/entry-count limits are exceeded, for zip and 7z.
  • Limits are enforced on bytes actually read, via streaming (no whole-entry buffering of untrusted input).
  • Tests in tests/core/tests/security.rs cover a crafted high-ratio archive and an excessive-entry-count archive.
  • docs/security.md updated: move decompression bombs from "known limitations" to a documented measure.

Related: docs/security.md.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions