Safe Archive

One-liner safe-extract orchestrator for adversarial archives. Combines b.archive.read + b.guardArchive.inspect + b.guardFilename. verifyExtractionPath + zip-bomb + entry-type policy + audit chain into a single call.

The 90%-case workflow — operator receives a hostile-shaped archive from an upload / external system / pipeline, wants to extract it into a quarantine directory with every defense default-on, and doesn't want to learn the read/guard/safeDecompress composition surface to do it.

b.safeArchive.extract({ source, destination, ... }) does the composition for them. Operators with fine-grained control needs reach for b.archive.read.zip(adapter) directly + assemble the pipeline manually.

Format auto-detection sniffs the first ~512 bytes for magic signatures: ZIP (LFH magic 0x04034b50 + EOCD magic 0x06054b50), tar (ustar at offset 257), gzip / tar.gz (RFC 1952 magic), and b.archive.wrap recipient (BAWRP) / passphrase (BAWPP) envelopes (auto-unwrapped before format detection). Unrecognized inputs are flagged safe-archive/format-unsupported.

The orchestrator refuses the WHOLE archive on any single critical guard issue — no partial extraction. Cleanup is fs.rm-recursive on the destination if extraction was interrupted, so a failed extract leaves no half-state on disk.

b.safeArchive.extract(opts) #

stable0.12.7hipaapci-dssgdprsoc2
{
  source:           b.archive.adapters.* | Buffer | string,
  destination:      string (target directory; created if missing),
  format:           "auto" | "zip" | "tar" | "tar.gz",
  bombPolicy:       b.guardArchive.zipBombPolicy(...) | { ... },
  entryTypePolicy:  b.guardArchive.entryTypePolicy(...) | { ... },
  guardProfile:     "strict" | "balanced" | "permissive" | "hipaa" | ...,
  audit:            b.audit,
  signal:           AbortSignal,
}

Safe-extract orchestrator. Combines read + guard + path-safety + bomb caps + audit in one call.

Refuses the whole archive on: - Format auto-detect mismatch (unknown / unsupported format). - Any critical guard issue (CVE-2025-3445 Zip Slip class + path traversal + symlink-escape + nested archive + encrypted entry). - PATH_MAX overflow on any entry name (CVE-2025-4517 defense). - Bomb-policy breach (entry-count / per-entry size / total size / expansion ratio). - LFH/CD skew on any entry.

var result = await b.safeArchive.extract({
  source:      b.archive.adapters.fs("/var/uploads/payload.zip"),
  destination: "/var/quarantine",
  guardProfile: "strict",
});
// → { entries: [{ name, bytesWritten, path }, ...], bytesExtracted, format }

b.safeArchive.extractToMemory(opts) #

stable0.14.13hipaapci-dssgdprsoc2
{
  source:           b.archive.adapters.* | Buffer | string,
  format:           "auto" | "zip" | "tar" | "tar.gz",
  bombPolicy:       b.guardArchive.zipBombPolicy(...) | { ... },
  entryTypePolicy:  b.guardArchive.entryTypePolicy(...) | { ... },
  guardProfile:     "strict" | "balanced" | "permissive" | "hipaa" | ...,
  recipient:        { privateKey, ecPrivateKey },  // for BAWRP envelopes
  passphrase:       string | Buffer,               // for BAWPP envelopes
  audit:            b.audit,
  signal:           AbortSignal,
}

In-memory counterpart to b.safeArchive.extract for read-only / serverless filesystems. Resolves the source, sniffs the format, auto-unwraps recipient (BAWRP) / passphrase (BAWPP) envelopes, and dispatches to the zip / tar / tar.gz reader's in-memory extractEntries — an async generator that yields each regular file entry's decompressed bytes without ever writing to disk. Takes no destination; the caller owns where, if anywhere, the bytes land.

Every defense the disk extract runs applies unchanged: the zip-bomb caps (entry-count / per-entry / total / expansion-ratio), the b.guardArchive metadata cascade (Zip-Slip / path-traversal / symlink- escape / encrypted-entry refusal — CVE-2025-3445 class), and the entry-type policy. Directory entries carry no bytes and are skipped. The disk-only realpath-agreement check (CVE-2025-4517 PATH_MAX TOCTOU defense) is intentionally absent — there is no extraction root — so the archive-level name refusals carry the containment guarantee here.

Trusted-stream adapter sources are refused upfront: the adversarial-safe central-directory walk requires random access. Collect the bytes into a buffer adapter, or read with b.archive.read.zip.fromTrustedStream directly.

for await (var entry of b.safeArchive.extractToMemory({
  source:       b.archive.adapters.fs("/var/uploads/payload.zip"),
  guardProfile: "strict",
})) {
  // entry → { name, bytes, size } — never touches disk
  await store.put(entry.name, entry.bytes);
}

b.safeArchive.inspect(opts) #

stable0.12.7
{
  source:          b.archive.adapters.* | Buffer | string,
  format:          "auto" | "zip",
  bombPolicy:      { ... },
  audit:           b.audit,
}

Read-only inspect: format sniffing + entry-list enumeration without decompression. Operators previewing an uploaded archive before committing to extraction reach for this primitive.

var summary = await b.safeArchive.inspect({
  source: b.archive.adapters.fs("/var/uploads/payload.zip"),
});
// → { format: "zip", entries: [...], totalCompressedBytes, totalUncompressedBytes }

Last updated 2026-08-08T16:39:49.652Z by seeder.