Skip to main content

Memory-safe archive extraction library with built-in security validation

Project description

exarch

PyPI Python CI License

Memory-safe archive extraction and creation library for Python.

Important: exarch is designed as a secure replacement for vulnerable archive libraries like Python's tarfile, which has known CVEs with CVSS scores up to 9.4.

This package provides Python bindings for exarch-core, a Rust library with built-in protection against common archive vulnerabilities.

Installation

pip install exarch

Tip: Use uv pip install exarch for faster installation.

Alternative Package Managers

# Poetry
poetry add exarch

# Pipenv
pipenv install exarch

Requirements

  • Python >= 3.10

Quick Start

Extraction

import exarch

result = exarch.extract_archive("archive.tar.gz", "/output/path")
print(f"Extracted {result.files_extracted} files")

Creation

import exarch

result = exarch.create_archive("backup.tar.gz", ["src/", "Cargo.toml"])
print(f"Created archive with {result.files_added} files")

Usage

Basic Extraction

import exarch

result = exarch.extract_archive("archive.tar.gz", "/output/path")

print(f"Files extracted: {result.files_extracted}")
print(f"Bytes written: {result.bytes_written}")
print(f"Duration: {result.duration_ms}ms")

With pathlib.Path

from pathlib import Path
import exarch

archive = Path("archive.tar.gz")
output = Path("/output/path")

result = exarch.extract_archive(archive, output)

Custom Security Configuration

import exarch

config = exarch.SecurityConfig()
config = config.max_file_size(100 * 1024 * 1024)  # 100 MB

result = exarch.extract_archive("archive.tar.gz", "/output", config)

Error Handling

import exarch

try:
    result = exarch.extract_archive("archive.tar.gz", "/output")
    print(f"Extracted {result.files_extracted} files")
except exarch.PathTraversalError as e:
    print(f"Blocked path traversal: {e}")
except exarch.ZipBombError as e:
    print(f"Zip bomb detected: {e}")
except exarch.SecurityViolationError as e:
    print(f"Security violation: {e}")
except exarch.ArchiveError as e:
    print(f"Extraction failed: {e}")

API Reference

extract_archive(archive_path, output_dir, config=None)

Extract an archive to the specified directory with security validation.

Parameters:

Name Type Description
archive_path str | Path Path to the archive file
output_dir str | Path Directory where files will be extracted
config SecurityConfig Optional security configuration

Returns: ExtractionReport

Attribute Type Description
files_extracted int Number of files extracted
directories_created int Number of directories created
symlinks_created int Number of symlinks created
bytes_written int Total bytes written
duration_ms int Extraction duration in milliseconds
files_skipped int Number of files skipped (e.g. duplicates)
warnings list[str] Warning messages generated during extraction

Raises:

Exception Description
PathTraversalError Path traversal attempt detected
SymlinkEscapeError Symlink points outside extraction directory
HardlinkEscapeError Hardlink target outside extraction directory
ZipBombError Potential zip bomb detected
QuotaExceededError Resource quota exceeded
SecurityViolationError Security policy violation
UnsupportedFormatError Archive format not supported
UnknownFormatError Archive format cannot be determined from path or magic bytes (subclass of UnsupportedFormatError)
InvalidArchiveError Archive is corrupted
IOError I/O operation failed

Note: Since v0.4.0, create_archive raises FileNotFoundError for missing sources, FileExistsError when the output already exists without overwrite, and ValueError for invalid compression levels — matching standard Python conventions.

extract_archive_with_progress(archive_path, output_dir, config, progress)

Extract an archive with a progress callback. The GIL is held when a callback is provided and released otherwise.

Parameters:

Name Type Description
archive_path str | Path Path to the archive file
output_dir str | Path Directory where files will be extracted
config SecurityConfig | None Optional security configuration
progress Callable[[str, int, int, int], None] | None Optional progress callback: (path, total_files, current_file, bytes_written)
import exarch

def on_progress(path: str, total: int, current: int, bytes_written: int) -> None:
    print(f"[{current}/{total}] {path} ({bytes_written} bytes)")

result = exarch.extract_archive_with_progress(
    "archive.tar.gz", "/output", config=None, progress=on_progress
)

SecurityConfig

Builder-style security configuration.

config = exarch.SecurityConfig()
config = config.max_file_size(100 * 1024 * 1024)        # 100 MB per file
config = config.max_total_size(1024 * 1024 * 1024)      # 1 GB total
config = config.max_file_count(10_000)                   # Max 10k files
config = config.max_compression_ratio(50.0)              # Zip bomb threshold
config = config.allowed_extensions([".txt", ".md"])      # Extension allowlist
config = config.banned_path_components(["__MACOSX"])     # Skip components
config = config.allow_solid_archives(True)               # Allow solid 7z archives

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 Python's standard tarfile module, exarch applies security validation by default.

Supported Formats

Format Extensions Extract Create List Verify
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. Unix symlinks inside 7z archives are reported as regular files (sevenz-rust2 API limitation).

Comparison with tarfile

# UNSAFE - tarfile has known vulnerabilities (CVE-2007-4559)
import tarfile
with tarfile.open("archive.tar.gz") as tar:
    tar.extractall("/output")  # May extract outside target directory!

# SAFE - exarch validates all paths
import exarch
exarch.extract_archive("archive.tar.gz", "/output")  # Protected by default

Development

This package is built using PyO3 and maturin.

# Clone repository
git clone https://github.com/bug-ops/exarch
cd exarch/crates/exarch-python

# Build with maturin
pip install maturin
maturin develop

# Run tests
pytest tests/

Related Packages

License

Licensed under either of:

at your option.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

exarch-0.4.1-cp39-abi3-win_amd64.whl (1.1 MB view details)

Uploaded CPython 3.9+Windows x86-64

exarch-0.4.1-cp39-abi3-musllinux_1_2_x86_64.whl (1.6 MB view details)

Uploaded CPython 3.9+musllinux: musl 1.2+ x86-64

exarch-0.4.1-cp39-abi3-musllinux_1_2_aarch64.whl (1.5 MB view details)

Uploaded CPython 3.9+musllinux: musl 1.2+ ARM64

exarch-0.4.1-cp39-abi3-manylinux_2_34_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.34+ x86-64

exarch-0.4.1-cp39-abi3-manylinux_2_34_aarch64.whl (1.3 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.34+ ARM64

exarch-0.4.1-cp39-abi3-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

exarch-0.4.1-cp39-abi3-macosx_10_12_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.9+macOS 10.12+ x86-64

File details

Details for the file exarch-0.4.1-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: exarch-0.4.1-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for exarch-0.4.1-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 cd5b4eace45f7688ca1b4fa803a501296febcac77e96c22f67fd5e2f350dfe0f
MD5 d9d7cee522a2470f367511e5779aa38d
BLAKE2b-256 ccbfa4e439fbd83d8b56951d784153ac152f6e5d752732be69c2fa2d13b2506b

See more details on using hashes here.

Provenance

The following attestation bundles were made for exarch-0.4.1-cp39-abi3-win_amd64.whl:

Publisher: release.yml on bug-ops/exarch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file exarch-0.4.1-cp39-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for exarch-0.4.1-cp39-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 140af4d7e1f7dac0ac4e85b2e97ca513623292c20a827adbd4f5c3988a63df1f
MD5 3c083d97fec96f3f6ccbf1be75c8d08e
BLAKE2b-256 a35d128ff0c8c201f6455df472baa685c1d249572d55706788772edd474ba6ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for exarch-0.4.1-cp39-abi3-musllinux_1_2_x86_64.whl:

Publisher: release.yml on bug-ops/exarch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file exarch-0.4.1-cp39-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for exarch-0.4.1-cp39-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 b468247f655c2359fa2fecb717eb1e465bcb06dc2eeab4000caa0b8441ebaec9
MD5 ddc0d92d94a37aee3f98f14f8fb6fbad
BLAKE2b-256 e7a94b3552ede6911511ee53f6361cbb8710b9ac2142598472309b415192df7e

See more details on using hashes here.

Provenance

The following attestation bundles were made for exarch-0.4.1-cp39-abi3-musllinux_1_2_aarch64.whl:

Publisher: release.yml on bug-ops/exarch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file exarch-0.4.1-cp39-abi3-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for exarch-0.4.1-cp39-abi3-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 61f2dc4451eb9a9bec964df836d180a544b3104879633354a48c2a010a80adb8
MD5 a9d1e6542bbc9387a86e2ed4c142175a
BLAKE2b-256 38a0cd34bb4030f90e9e9d54a0930872ced8d58988ca8015bc58c216309f61a9

See more details on using hashes here.

Provenance

The following attestation bundles were made for exarch-0.4.1-cp39-abi3-manylinux_2_34_x86_64.whl:

Publisher: release.yml on bug-ops/exarch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file exarch-0.4.1-cp39-abi3-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for exarch-0.4.1-cp39-abi3-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 99d4d1c9da065232d1ebbd6a23b2440edafa025270267e683d31bcc848e5b52a
MD5 c71eb477b5fba3e8908c291637a89da0
BLAKE2b-256 04568b2b5af3aae086e446dfa6f8c6a125f201ecf1e6d5778dbb5654e830e9d5

See more details on using hashes here.

Provenance

The following attestation bundles were made for exarch-0.4.1-cp39-abi3-manylinux_2_34_aarch64.whl:

Publisher: release.yml on bug-ops/exarch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file exarch-0.4.1-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for exarch-0.4.1-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 042127637ec0cf1d3bb816c073ed352cbd9d1e8b1bfd7e7a99297a464dea8e41
MD5 8fec6bbc6f1f22462c69eb9d4db4bb48
BLAKE2b-256 b90043dcaa69717a4d3ad8cd4859b494dbe534cf4695442a64dc8fb13e5284d7

See more details on using hashes here.

Provenance

The following attestation bundles were made for exarch-0.4.1-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on bug-ops/exarch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file exarch-0.4.1-cp39-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for exarch-0.4.1-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 7a4564eacc58c336e07f5e202782ad5c5bffbcc90d884acff22aaba3195f08c4
MD5 aa93201ad48326b026743519eba30046
BLAKE2b-256 5fa4b29d42fd7fb9727396d43034aa87e15ff32bfc78f664f1bfff45a41a6665

See more details on using hashes here.

Provenance

The following attestation bundles were made for exarch-0.4.1-cp39-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on bug-ops/exarch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page