Skip to content

Dependencies

exav is a security tool, so what it links is part of its threat model. This page lists the dependencies of the shipped binary (exav, default features): the direct ones first — what each is for, its license, and its unsafe posture — then every transitive crate with the direct dependency that pulls it in, so the full supply chain is on one page. The dependency policy behind these choices is in the repository’s docs/DEPENDENCIES.md.

  • Safe Rust by default. exav’s own scanning and extraction code is written in safe Rust — exav-core and exav-unpack are #![forbid(unsafe_code)], so the crates that parse hostile input contain no unsafe of their own.
  • Pure Rust, no C, no JIT. The default build links no C libraries and no native code generator. Compression (flate2 uses the pure-Rust miniz_oxide backend, plus pure-Rust bzip2/xz/zstd/lzma crates) and crypto are all pure Rust. There is no wasmtime, no Cranelift, no OpenSSL, and no ring in the default binary.
  • A network server with no network crates. The ICAP server adds no dependency at all: its request framing, chunked decoding and Encapsulated offset parsing are written against std, in a module that carries #![deny(unsafe_code)] — the parsers a hostile client reaches first are exav’s own code, not a transitive one.
  • Minimal, contained unsafe. exav is not zero-unsafe overall: a small number of dependencies use unsafe internally, almost entirely for SIMD acceleration (byte search, hashing) and OS syscalls (the daemon). None of it is in exav’s own parsing logic, and driving the residual surface down is an explicit roadmap goal.
  • Feature-gated capability. Optional features (http, individual formats) only pull their dependencies when enabled — see Feature flags. The network stack is opt-in: it is the only thing that would link a non-pure-Rust crypto library (see Opt-in dependencies).

The default binary resolves to 151 third-party crates in total: the 60 direct dependencies exav explicitly chose (below) plus 91 transitive ones.

Crate Purpose License unsafe posture
clap Command-line argument parsing MIT OR Apache-2.0 safe
anyhow Error handling in the binary MIT OR Apache-2.0 safe
serde_json JSON scan-report output MIT OR Apache-2.0 safe
walkdir Recursive directory traversal Unlicense OR MIT safe
regex Linear-time regex (CLI filters) MIT OR Apache-2.0 safe (SIMD via memchr/aho-corasick)
libc Syscall bindings for the prefork daemon (signals, resource limits) MIT OR Apache-2.0 unsafe FFI declarations

Spilling an oversized stream to a temp file is not a dependency: it is exav/src/tmpfile.rs, a page of std::fs with the properties that matter (O_CREAT|O_EXCL, so a pre-planted symlink cannot be followed; 0600; delete on drop). The ready-made crates for it reach the filesystem through rustix and linux-raw-sys, which would add more unsafe than the rest of the tree combined — for a feature that never touches a scanned byte.

The engine crate is #![forbid(unsafe_code)]; the unsafe noted below lives inside these dependencies, not in exav.

Crate Purpose License unsafe posture
daachorse Double-array Aho-Corasick automaton (the main pattern matcher) MIT OR Apache-2.0 perf-critical indexing
aho-corasick Multi-pattern search (YARA atoms, prefilters) Unlicense OR MIT SIMD
memchr Vectorized byte search Unlicense OR MIT SIMD
regex-automata / regex-syntax Linear-time (DoS-safe) regex engine + parser MIT OR Apache-2.0 via memchr
fancy-regex Backtracking regex for wildcard-signature verification MIT safe
goblin PE / ELF / Mach-O executable parsing MIT safe
iced-x86 Not linked by any shipped binary. A dev-dependency of exav-x86 only, where it is the oracle its differential tests, table generator and fuzz target check against MIT handler dispatch through raw pointers, and integer-to-enum transmutes on table indices
md-5 / sha1 / sha2 Hash signatures (whole-file / section digests) MIT OR Apache-2.0 minimal (CPU-feature detection)
crc32fast CRC32 MIT OR Apache-2.0 SIMD
base64 Base64 decode (embedded payloads, YARA) MIT OR Apache-2.0 safe
bstr Byte-string utilities (YARA engine) MIT OR Apache-2.0 safe
yara-x-parser YARA grammar/AST parser (the native engine’s front end) BSD-3-Clause safe
image Icon/image decoding for fuzzy image hashing MIT OR Apache-2.0 some, in codec paths
rustdct / transpose DCT for perceptual image hashing MIT OR Apache-2.0 safe
tlsh2 TLSH fuzzy hashing Apache-2.0 OR BSD-3-Clause safe
rmp-serde / serde MessagePack (de)serialization of the prebuilt .exavdb MIT / MIT OR Apache-2.0 safe
thiserror Error-type derive MIT OR Apache-2.0 safe

Also #![forbid(unsafe_code)]. The decoders are pure-Rust; there is no C compression library in the tree.

Crate Purpose License unsafe posture
flate2 DEFLATE / gzip / zlib (pure-Rust miniz_oxide backend) MIT OR Apache-2.0 safe (no C zlib)
deflate64 Deflate64 (ZIP method 9) MIT noneforbid
bzip2-rs bzip2 (pure Rust) MIT OR Apache-2.0 safe
xz4rust XZ / LZMA (pure Rust) MIT safe
lzma-rust2 LZMA / LZMA2 (7z) Apache-2.0 safe
ruzstd Zstandard (pure Rust) MIT safe
lzxd LZX (CAB) MIT OR Apache-2.0 safe
lzfse_rust LZFSE / LZVN (DMG) MIT OR Apache-2.0 safe
delharc LHA / LZH MIT OR Apache-2.0 safe
bitstream-io Bit-level readers for decoders MIT OR Apache-2.0 safe
tar tar archives (xattr disabled — drops syscall unsafe) MIT OR Apache-2.0 safe
zip ZIP container parsing MIT safe
cfb OLE2 / Compound File Binary (Office) MIT safe
quick-xml OOXML / XML parsing MIT safe
mail-parser MIME / email parsing Apache-2.0 OR MIT safe
apfs / hfsplus DMG filesystem parsing MIT safe
ext4-view ext2/3/4 filesystem walking (virtual disks) MIT OR Apache-2.0 noneforbid
fatfs FAT12/16/32 cluster-chain walking MIT 13
lznt1 LZNT1 (NTFS compressed streams) MIT noneforbid
salzweg LZW (ZOO, Unix compress) MIT none
unshield InstallShield .z archives MIT none
byteorder / bincode Byte-order + binary (de)serialization Unlicense OR MIT / MIT safe

Cryptographic primitives (the decrypt feature)

Section titled “Cryptographic primitives (the decrypt feature)”

Used only to decrypt encrypted archive members. These are RustCrypto crates; their residual unsafe is confined to SIMD/CPU-feature detection.

Crate Purpose License unsafe posture
aes / cbc AES block cipher + CBC (ZIP/7z/DMG) MIT OR Apache-2.0 minimal (CPU-feature detection)
des DES (legacy archive encryption) MIT OR Apache-2.0 safe
hmac / pbkdf2 / digest Key derivation + MAC MIT OR Apache-2.0 safe
constant_time_eq Constant-time comparison CC0-1.0 OR MIT-0 OR Apache-2.0 safe
stringprep Password normalization MIT OR Apache-2.0 safe

Opt-in dependencies (not in the default binary)

Section titled “Opt-in dependencies (not in the default binary)”

Enabled only by the http feature (URL scanning / signature auto-update), handled by the separate exav-update crate:

Crate Purpose License Note
ureq Minimal blocking HTTP(S) client MIT OR Apache-2.0 pulls rustlsring

ring bundles C/assembly crypto — it is the one non-pure-Rust component exav can pull, which is exactly why HTTP is off by default. Builds that don’t need network fetch never link it.

The tables above are the crates exav chose. Those crates pull in their own dependencies, and a security tool’s real supply chain is the whole closure — so here it is: every remaining crate in the default exav build, with the direct dependency (or dependencies) that pulls it in.

The default exav build resolves to 159 packages, five of which are exav’s own workspace crates (exav, exav-core, exav-unpack, exav-pe-emu, exav-x86). bitflags, hashbrown and rustc-hash each resolve at two major versions, so the count of distinct projects is lower still. Check it against the current lockfile with:

Terminal window
cargo tree -e no-dev -p exav --prefix none | sed 's/ (\*)$//' \
| awk '{print $1}' | sort -u | wc -l

Nothing here is a C library, a TLS stack, or a code generator. syn, quote and proc-macro2 are build-time proc-macro machinery and contribute no runtime code to the binary.

35 of the 94 packages contain no unsafe at all, 17 of those enforcing it with a crate-root #![forbid(unsafe_code)]. The unsafe uses column counts occurrences of the unsafe keyword in each crate’s shipped src/ (comments stripped; tests, benches and examples excluded) at the exact version this build resolves. Read it as surface area to review, not as risk: a count is not a defect, and the concentration is unsurprising — rustfft (SIMD butterflies, reached only through the perceptual image hash), hashbrown and bytemuck are 2,496 of the 3,490 occurrences in this table, and none of them sits on a path that parses scanned bytes. There are no raw-syscall binding crates here at all — the two that would otherwise dominate the count, rustix and linux-raw-sys, are kept out by writing the daemon’s spill file in-tree and by building tar without xattr. Reproduce the count with cargo geiger, or per crate with:

Terminal window
grep -rc '\bunsafe\b' ~/.cargo/registry/src/*/<crate>-<version>/src/
Crate License unsafe uses Pulled in by
adler2 0BSD OR MIT OR Apache-2.0 noneforbid flate2, image, zip
anstream MIT OR Apache-2.0 3 clap
anstyle MIT OR Apache-2.0 1 clap
anstyle-parse MIT OR Apache-2.0 3 clap
anstyle-query MIT OR Apache-2.0 1 clap
arraydeque MIT/Apache-2.0 77 explode
ascii_tree MIT none yara-x-parser
beef MIT OR Apache-2.0 26 yara-x-parser
bit-set Apache-2.0 OR MIT 2 fancy-regex
bit-vec Apache-2.0 OR MIT 4 fancy-regex
bitflags MIT OR Apache-2.0 2 delharc, image, yara-x-parser
block-buffer MIT OR Apache-2.0 4 digest, hmac, md-5, pbkdf2, sha1, sha2
block-padding MIT OR Apache-2.0 1 aes, cbc, des
bytemuck Zlib OR Apache-2.0 OR MIT 318 image
cfg-if MIT OR Apache-2.0 none aes, bzip2-rs, crc32fast, flate2, image, md-5, sha1, sha2, tar, zip
chrono MIT OR Apache-2.0 11 delharc
cipher MIT OR Apache-2.0 2 aes, cbc, des
clap_builder MIT OR Apache-2.0 noneforbid clap
clap_derive MIT OR Apache-2.0 noneforbid clap
clap_lex MIT OR Apache-2.0 6 clap
color_quant MIT none image
colorchoice MIT OR Apache-2.0 none clap
countme MIT OR Apache-2.0 1 yara-x-parser
cpufeatures MIT OR Apache-2.0 9 aes, sha1, sha2
crc MIT OR Apache-2.0 noneforbid ext4-view
crc-catalog MIT OR Apache-2.0 noneforbid crc
crypto-common MIT OR Apache-2.0 noneforbid aes, cbc, des, digest, hmac, md-5, pbkdf2, sha1, sha2
either MIT OR Apache-2.0 2 yara-x-parser
equivalent Apache-2.0 OR MIT none mail-parser, yara-x-parser, zip
explode MIT 6 unshield
fdeflate MIT OR Apache-2.0 noneforbid image
filetime MIT/Apache-2.0 9 tar
fnv Apache-2.0 / MIT none cfb, yara-x-parser
generic-array MIT 78 aes, cbc, des, digest, hmac, md-5, pbkdf2, sha1, sha2
gif MIT OR Apache-2.0 noneforbid image
hashbrown MIT OR Apache-2.0 759 (two versions resolve: 454 + 305) mail-parser, yara-x-parser, zip
hashify Apache-2.0 OR MIT none mail-parser
heck MIT OR Apache-2.0 noneforbid clap
iana-time-zone MIT OR Apache-2.0 212 delharc
indexmap Apache-2.0 OR MIT 11 mail-parser, yara-x-parser, zip
inout MIT OR Apache-2.0 22 aes, cbc, des
is_terminal_polyfill MIT OR Apache-2.0 none clap
itertools MIT OR Apache-2.0 10 yara-x-parser
itoa MIT OR Apache-2.0 13 serde_json
jpeg-decoder MIT OR Apache-2.0 16 image
lazy_static MIT OR Apache-2.0 2 iced-x86, yara-x-parser
log MIT OR Apache-2.0 6 goblin
logos MIT OR Apache-2.0 18 yara-x-parser
logos-codegen MIT OR Apache-2.0 4 yara-x-parser
logos-derive MIT OR Apache-2.0 none yara-x-parser
miniz_oxide MIT OR Zlib OR Apache-2.0 noneforbid flate2, image, zip
no_std_io2 Apache-2.0 OR MIT 11 bitstream-io
num-complex MIT OR Apache-2.0 2 rustdct
num-integer MIT OR Apache-2.0 none rustdct, transpose
num-traits MIT OR Apache-2.0 1 delharc, image, rmp-serde, rustdct, transpose, yara-x-parser
plain MIT/Apache-2.0 23 goblin
png MIT OR Apache-2.0 noneforbid image
primal-check MIT OR Apache-2.0 none rustdct
proc-macro2 MIT OR Apache-2.0 6 apfs, bincode, clap, goblin, hfsplus, mail-parser, rmp-serde, serde, thiserror, yara-x-parser
quote MIT OR Apache-2.0 none apfs, bincode, clap, goblin, hfsplus, mail-parser, rmp-serde, serde, thiserror, yara-x-parser
rmp MIT 1 rmp-serde
rowan MIT OR Apache-2.0 55 yara-x-parser
rustc-hash Apache-2.0 OR MIT none yara-x-parser
rustfft MIT OR Apache-2.0 1419 rustdct
same-file Unlicense/MIT 3 walkdir
scroll MIT 7 goblin
scroll_derive MIT 1 goblin
serde_core MIT OR Apache-2.0 2 bincode, rmp-serde, serde, serde_json
serde_derive MIT OR Apache-2.0 none bincode, rmp-serde, serde
simd-adler32 MIT 36 flate2, image, zip
strength_reduce MIT OR Apache-2.0 none rustdct, transpose
strsim MIT noneforbid clap
subtle BSD-3-Clause 2 digest, hmac, md-5, pbkdf2, sha1, sha2
syn MIT OR Apache-2.0 71 apfs, bincode, clap, goblin, hfsplus, mail-parser, rmp-serde, serde, thiserror, yara-x-parser
text-size MIT OR Apache-2.0 noneforbid yara-x-parser
thiserror-impl MIT OR Apache-2.0 1 apfs, hfsplus, thiserror
tiff MIT 2 image
tinyvec Zlib OR Apache-2.0 OR MIT noneforbid bzip2-rs, stringprep
tinyvec_macros MIT OR Apache-2.0 OR Zlib noneforbid bzip2-rs, stringprep
twox-hash MIT 72 ruzstd
typed-path MIT OR Apache-2.0 32 zip
typenum MIT OR Apache-2.0 noneforbid aes, cbc, des, digest, hmac, md-5, pbkdf2, sha1, sha2
unicode-bidi MIT OR Apache-2.0 1 stringprep
unicode-ident (MIT OR Apache-2.0) AND Unicode-3.0 2 apfs, bincode, clap, goblin, hfsplus, mail-parser, rmp-serde, serde, thiserror, yara-x-parser
unicode-normalization MIT OR Apache-2.0 5 stringprep
unicode-properties MIT/Apache-2.0 none stringprep
utf8parse Apache-2.0 OR MIT 1 clap
uuid Apache-2.0 OR MIT 9 cfb
web-time MIT OR Apache-2.0 none cfb
weezl MIT OR Apache-2.0 noneforbid image
zmij MIT 74 serde_json

Nothing here has to be taken on trust — regenerate the tables above and check them:

Terminal window
# Direct + transitive dependencies of the default binary, with licenses.
# --no-dedupe (or --invert <crate>) is what shows every "pulled in by" edge:
cargo tree -p exav -e normal --no-dedupe --format "{p} {l}"
# Audit advisories, bans, and the license allowlist (also run in CI):
cargo deny check
cargo audit