Memory-safe archive extraction library with built-in security validation
npm install exarch-rs




Memory-safe archive extraction and creation library for Node.js.
> [!IMPORTANT]
> exarch is designed as a secure replacement for vulnerable archive libraries like tar-fs, which has known CVEs with CVSS scores up to 9.4.
This package provides Node.js bindings for exarch-core, a Rust library with built-in protection against common archive vulnerabilities.
``bashnpm
npm install exarch-rs
> [!NOTE]
> This package includes TypeScript definitions. No need for separate
@types package.Requirements
- Node.js >= 18
Quick Start
$3
`javascript
const { extractArchive } = require('exarch-rs');// Async (recommended)
const result = await extractArchive('archive.tar.gz', '/output/path');
console.log(
Extracted ${result.filesExtracted} files);
`$3
`javascript
const { createArchive } = require('exarch-rs');// Async (recommended)
const result = await createArchive('backup.tar.gz', ['src/', 'package.json']);
console.log(
Created archive with ${result.filesAdded} files);
`Usage
$3
`javascript
const { extractArchive } = require('exarch-rs');const result = await extractArchive('archive.tar.gz', '/output/path');
console.log(
Files extracted: ${result.filesExtracted});
console.log(Bytes written: ${result.bytesWritten});
console.log(Duration: ${result.durationMs}ms);
`$3
`javascript
const { extractArchiveSync } = require('exarch-rs');const result = extractArchiveSync('archive.tar.gz', '/output/path');
console.log(
Extracted ${result.filesExtracted} files);
`> [!TIP]
> Prefer the async API to avoid blocking the event loop during extraction.
$3
`javascript
import { extractArchive } from 'exarch-rs';const result = await extractArchive('archive.tar.gz', '/output/path');
`$3
`typescript
import { extractArchive, SecurityConfig, ExtractionReport } from 'exarch-rs';const result: ExtractionReport = await extractArchive('archive.tar.gz', '/output/path');
console.log(
Extracted ${result.filesExtracted} files);
`$3
`typescript
import { extractArchive, SecurityConfig } from 'exarch-rs';const config = new SecurityConfig()
.maxFileSize(100 1024 1024) // 100 MB per file
.maxTotalSize(1024 1024 1024) // 1 GB total
.maxFileCount(10_000); // Max 10k files
const result = await extractArchive('archive.tar.gz', '/output', config);
`$3
`javascript
const { extractArchive } = require('exarch-rs');try {
const result = await extractArchive('archive.tar.gz', '/output');
console.log(
Success: ${result.filesExtracted} files);
} catch (error) {
// Error codes: PATH_TRAVERSAL, SYMLINK_ESCAPE, ZIP_BOMB, QUOTA_EXCEEDED, etc.
console.error(Extraction failed: ${error.message});
}
`API
$3
Extract an archive asynchronously with security validation.
Parameters:
| Name | Type | Description |
|------|------|-------------|
|
archivePath | string | Path to the archive file |
| outputDir | string | Directory where files will be extracted |
| config | SecurityConfig | Optional security configuration |Returns:
Promise$3
Synchronous version. Blocks the event loop until extraction completes.
Returns:
ExtractionReport$3
`typescript
interface ExtractionReport {
filesExtracted: number; // Number of files extracted
bytesWritten: number; // Total bytes written
durationMs: number; // Extraction duration in milliseconds
}
`$3
Builder-style security configuration.
`typescript
const config = new SecurityConfig()
.maxFileSize(bytes) // Max size per file
.maxTotalSize(bytes) // Max total extraction size
.maxFileCount(count) // Max number of files
.maxCompressionRatio(n); // Max compression ratio (zip bomb detection)
`Security Features
The library provides built-in protection against:
| Protection | Description |
|------------|-------------|
| Path traversal | Blocks
../ and absolute paths |
| Symlink attacks | Prevents symlinks escaping extraction directory |
| Hardlink attacks | Validates hardlink targets |
| Zip bombs | Detects high compression ratios |
| Permission sanitization | Strips setuid/setgid bits |
| Size limits | Enforces file and total size limits |> [!CAUTION]
> Unlike many Node.js archive libraries, exarch applies security validation by default.
Supported Formats
| Format | Extensions | Extract | Create |
|--------|------------|:-------:|:------:|
| TAR |
.tar | ✅ | ✅ |
| TAR+GZIP | .tar.gz, .tgz | ✅ | ✅ |
| TAR+BZIP2 | .tar.bz2, .tbz2 | ✅ | ✅ |
| TAR+XZ | .tar.xz, .txz | ✅ | ✅ |
| TAR+ZSTD | .tar.zst, .tzst | ✅ | ✅ |
| ZIP | .zip | ✅ | ✅ |
| 7z | .7z | ✅ | — |> [!NOTE]
> 7z creation is not yet supported. Solid and encrypted 7z archives are rejected for security reasons.
Comparison with tar-fs
`javascript
// UNSAFE - tar-fs has known vulnerabilities
const tar = require('tar-fs');
const fs = require('fs');
fs.createReadStream('archive.tar')
.pipe(tar.extract('/output')); // May extract outside target directory!// SAFE - exarch-rs validates all paths
const { extractArchive } = require('exarch-rs');
await extractArchive('archive.tar', '/output'); // Protected by default
`Development
This package is built using napi-rs.
`bash
Clone repository
git clone https://github.com/bug-ops/exarch
cd exarch/crates/exarch-nodeInstall dependencies
npm installBuild native module
npm run buildRun tests
npm test
``- exarch-core — Core Rust library
- exarch (PyPI) — Python bindings
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option.