Skip to content

Repository files navigation

archive-forensic

Peel every archive layer to reach the evidence — and catch the ones that lie about what they hold.

Crates.io (archive-core) Crates.io (archive-forensic) docs.rs Rust 1.93+ License: Apache-2.0 Sponsor

CI Coverage unsafe: forbidden Security audit

An archive is a transparent layer over your evidence — evidence.E01.gz should read exactly like evidence.E01.

archive-core is a pure-Rust, forbid(unsafe), read-only reader that peels gzip / bzip2 / xz / zip / 7z / tar layers to reach the inner artifact, choosing the codec by content magic (the authority for what was actually applied) and using the file name only as a secondary hint for aliases (.tgz / .tbz2) and the magic-absent formats. archive-forensic is the anomaly auditor layered on top of it.

Recursively unpack any nested archive to its leaf files, with archive-bomb guards:

use archive_core::{resolve, Limits, Node};

let bytes = std::fs::read("evidence.tar.gz.zip")?;
for node in resolve(&bytes, Some("evidence.tar.gz.zip"), &Limits::default())? {
    if let Node::File { name, bytes } = node {
        println!("{name}: {} bytes", bytes.len());
    }
}
# Ok::<(), archive_core::ArchiveError>(())

resolve peels layer after layer (zip → tar.gz → tar → …) until it reaches real files, capping cumulative depth, inflated size, and member count so a decompression bomb fails loud instead of exhausting memory. For a single peel use peel_bytes; to read members of one archive without recursing use Archive.

The two crates

crate role
archive-core the peel / archive-layer reader + format detection: single-layer peel_bytes, recursive resolve with bomb guards, member reading via Archive, segment reassembly (split / EWF .E0n / raw .00n), and the phase-1 detect access-plan. Reuses the fleet readers zip-forensic-core (zip) and sevenz-rust2 (7z), plus pure-Rust flate2 / bzip2.
archive-forensic the anomaly auditor over archive-core: extension-vs-content masquerade, CRC / declared-size lies, path-traversal member names, decompression-bomb signatures.

Status: under active TDD construction. The reader (zip/7z/tar/gzip/bzip2 peel, recursive resolve, segment reassembly, and the optional vfs ArchiveOpener adapter) is wired and validated; the archive-forensic audit surface lands as archive-core's tree API grows.

Trust, but verify

  • Pure-Rust, no C-FFI codecs. forbid(unsafe) across the whole workspace; the compression stack (flate2/miniz_oxide, bzip2-rs/libbz2-rs-sys, lzma-rust2, ruzstd) is pure-Rust — no bundled C is compiled or linked.
  • Panic-free by lint. unwrap_used / expect_used denied in production code; the bomb guards (depth / cumulative-inflated-size / entry-count caps) fail loud.
  • Input-fuzzed. cargo-fuzz targets drive peel_bytes, resolve, and Archive::open/read on arbitrary bytes — invariant never panic.
  • Validated against reference-tool archives. Fixtures are minted by GNU tar, Info-ZIP, 7-Zip, and CPython and read back byte-for-byte — see docs/validation.md.

Documentation

Full docs, including the validation write-up, are published at securityronin.github.io/archive-forensic.


Privacy Policy · Terms of Service · © 2026 Security Ronin Ltd

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages