{"id":51595169,"url":"https://github.com/securityronin/zip-forensic","last_synced_at":"2026-07-11T18:01:37.695Z","repository":{"id":368398253,"uuid":"1284465551","full_name":"SecurityRonin/zip-forensic","owner":"SecurityRonin","description":"Pure-Rust forensic ZIP toolkit: zip-full-core reader (no C-FFI, all common codecs + decryption) and zip-forensic anomaly auditor","archived":false,"fork":false,"pushed_at":"2026-06-30T10:42:08.000Z","size":287,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-30T12:23:44.546Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SecurityRonin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-29T22:25:16.000Z","updated_at":"2026-06-30T10:42:14.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/SecurityRonin/zip-forensic","commit_stats":null,"previous_names":["securityronin/zip-forensic"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/SecurityRonin/zip-forensic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Fzip-forensic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Fzip-forensic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Fzip-forensic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Fzip-forensic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SecurityRonin","download_url":"https://codeload.github.com/SecurityRonin/zip-forensic/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Fzip-forensic/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35370428,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-11T02:00:05.354Z","response_time":104,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-11T18:01:36.278Z","updated_at":"2026-07-11T18:01:37.690Z","avatar_url":"https://github.com/SecurityRonin.png","language":"Rust","funding_links":["https://github.com/sponsors/h4x0r"],"categories":[],"sub_categories":[],"readme":"# zip-forensic\n\n[![Crates.io: zip-forensic-core](https://img.shields.io/crates/v/zip-forensic-core?label=zip-forensic-core)](https://crates.io/crates/zip-forensic-core)\n[![Crates.io: zip-forensic](https://img.shields.io/crates/v/zip-forensic?label=zip-forensic)](https://crates.io/crates/zip-forensic)\n[![Docs.rs](https://img.shields.io/docsrs/zip-forensic-core?label=docs.rs)](https://docs.rs/zip-forensic-core)\n[![Rust 1.87+](https://img.shields.io/badge/rust-1.87%2B-blue.svg)](https://www.rust-lang.org)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Sponsor](https://img.shields.io/badge/sponsor-h4x0r-ea4aaa?logo=githubsponsors)](https://github.com/sponsors/h4x0r)\n\n[![CI](https://github.com/SecurityRonin/zip-forensic/actions/workflows/ci.yml/badge.svg)](https://github.com/SecurityRonin/zip-forensic/actions/workflows/ci.yml)\n[![Docs](https://img.shields.io/badge/docs-mkdocs-blue)](https://securityronin.github.io/zip-forensic/)\n[![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/)\n[![Fuzzed](https://img.shields.io/badge/fuzzed-cargo--fuzz-success.svg)](fuzz/)\n\n**Audit a ZIP for tampering, and read every common codec — in pure Rust, with zero C-FFI dependencies.**\n\n```rust\n// Surface where an archive's central directory disagrees with its local headers —\n// the classic post-hoc-edit signal a happy-path reader silently trusts.\nfor anomaly in zip_forensic::audit_path(\"evidence.zip\".as_ref())? {\n    println!(\"[{:?}] {}: {}\", anomaly.severity, anomaly.code, anomaly.note);\n}\n// [High] ZIP-CD-LFH-MISMATCH: entry 3 (report.docx): central-directory crc32\n//   (0x1a2b3c4d) disagrees with the local file header (0x00000000) — consistent\n//   with a post-hoc edit of one copy\n```\n\nThat's it — point it at a zip and read graded findings. Each is an observation\n(\"consistent with\"), never a verdict, and converts to a\n[`forensicnomicon`](https://crates.io/crates/forensicnomicon) `Finding`.\n\n## Read entries without the C libraries\n\n`zip-forensic-core` parses the container and decodes every common method with **only\npure-Rust crates** — the three C libraries the popular `zip` crate pulls\n(`bzip2-sys`, `zstd-sys`, `lzma-sys`) are gone:\n\n```rust\nuse std::io::Read;\nlet mut archive = zip_core::ZipArchive::new(std::fs::File::open(\"eg.zip\")?)?;\nlet mut entry = archive.by_name(\"data.bin\")?;   // Stored/Deflate/Deflate64/Bzip2/Zstd/LZMA/XZ\nlet mut bytes = Vec::new();\nentry.read_to_end(\u0026mut bytes)?;                 // CRC-32 verified on EOF; fails loud on mismatch\n```\n\n```console\n$ cargo tree -p zip-forensic-core -e normal | grep -- -sys\n$            # empty — no C-FFI in the runtime tree\n```\n\nEncrypted entries decrypt with a password — traditional ZipCrypto and WinZip AES\n(128/192/256), the latter on audited RustCrypto with HMAC verification:\n\n```rust\nlet mut entry = archive.by_name_decrypt(\"secret.bin\", b\"password\")?;\n// plain by_name() refuses an encrypted entry — secure by default\n```\n\n## Random-access a disk image inside a zip — no extraction\n\nA forensic image stored in a ZIP at ~0% compression is, at the deflate level, a\nrun of byte-aligned *stored* blocks. `zip-forensic-core` indexes them so any offset is\naddressable directly, with no full inflation and no temp spill:\n\n```rust\nlet entry = zip_core::open_entry(\"case.zip\".as_ref(), \"image.E01\")?;\nlet mut buf = vec![0u8; 4096];\nentry.read_at(\u0026mut buf, 1_000_000_003)?;        // positioned read, lock-free, no decompression from start\n```\n\n## Install\n\n```toml\n[dependencies]\nzip-forensic-core = \"0.2\"        # the reader\nzip-forensic = \"0.2\"    # the auditor\n```\n\n## Safety\n\n`#![forbid(unsafe_code)]`, panic-free on untrusted input (bounds-checked reads,\nentry-count and decompression-bomb caps), `enclosed_name()` refuses\npath-traversal names, and three `cargo-fuzz` targets assert the parser, decoder,\nand audit pipeline never panic. Correctness is established against independent\noracles — see the [validation notes](https://securityronin.github.io/zip-forensic/validation/).\n\n---\n\n[Privacy Policy](https://securityronin.github.io/zip-forensic/privacy/) · [Terms of Service](https://securityronin.github.io/zip-forensic/terms/) · © 2026 Security Ronin Ltd\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecurityronin%2Fzip-forensic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsecurityronin%2Fzip-forensic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecurityronin%2Fzip-forensic/lists"}