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.with_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.with_max_file_size(100 * 1024 * 1024)   # 100 MB per file
config = config.with_max_total_size(1024 * 1024 * 1024) # 1 GB total
config = config.with_max_file_count(10_000)              # Max 10k files
config = config.with_max_compression_ratio(50.0)        # Zip bomb threshold
config = config.add_allowed_extension(".txt")            # Extension allowlist
config = config.add_allowed_extension(".md")
config = config.add_banned_component("__MACOSX")         # Skip components
config = config.with_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.5.0-cp39-abi3-win_amd64.whl (1.1 MB view details)

Uploaded CPython 3.9+Windows x86-64

exarch-0.5.0-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.5.0-cp39-abi3-musllinux_1_2_aarch64.whl (1.5 MB view details)

Uploaded CPython 3.9+musllinux: musl 1.2+ ARM64

exarch-0.5.0-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.5.0-cp39-abi3-manylinux_2_34_aarch64.whl (1.3 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.34+ ARM64

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

Uploaded CPython 3.9+macOS 11.0+ ARM64

exarch-0.5.0-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.5.0-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: exarch-0.5.0-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.5.0-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 40cbd3b14d2cf2a6e6d26fd1df6b2553819b50cc8efd17203b0e1f5617ff5610
MD5 2dc998953895fcc54d7b2d948e7665ad
BLAKE2b-256 26be10e2b1a5fcb71638ffd567771026d4b017c0def33fa5e5e0923664c4f970

See more details on using hashes here.

Provenance

The following attestation bundles were made for exarch-0.5.0-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.5.0-cp39-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for exarch-0.5.0-cp39-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 7a22300c7e7d8b5c1bf76b9203375dbb70eb8108c9b3215ee621f7e811d05444
MD5 7394a16399178924f3d7bae022bfbce6
BLAKE2b-256 e5ffddfad007d51a9377cfd2f31c17d5a78020f2fe5c8f56bf29a20cce9cacac

See more details on using hashes here.

Provenance

The following attestation bundles were made for exarch-0.5.0-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.5.0-cp39-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for exarch-0.5.0-cp39-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 2b0b17cb08467f5a7e67f5f83bf3613dee08d9655e27c7cc3876ec3f69adb5e6
MD5 18043747bc0fd92cfdf30c9d5ec84804
BLAKE2b-256 1e9a5952915d64491fabaaa9c3acc03346b6959e8f5b25e53337ff7591911fea

See more details on using hashes here.

Provenance

The following attestation bundles were made for exarch-0.5.0-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.5.0-cp39-abi3-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for exarch-0.5.0-cp39-abi3-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 85e5cd1ec10d8bcc7a2262aa77f84866095a07ddc2ef91562e5eaff6cef7ff66
MD5 5e467f736f6802eb6fe9de03fb4c6af7
BLAKE2b-256 149d4373affe4583c808f3645499566a6bdd7ba1cc2d9148566670ffd4e8a766

See more details on using hashes here.

Provenance

The following attestation bundles were made for exarch-0.5.0-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.5.0-cp39-abi3-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for exarch-0.5.0-cp39-abi3-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 a4af41e2fcf25d55b39b175a9d8d26e0b24db4a67de6bda2e335f6c9170abdaa
MD5 235ee3c0d1e56657f63d11f792bce884
BLAKE2b-256 eeb0e51b03dceb4d5536926d74caa166ed4c534168f2f6f8f72e5fc37521e3f8

See more details on using hashes here.

Provenance

The following attestation bundles were made for exarch-0.5.0-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.5.0-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for exarch-0.5.0-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f38ed65022af6575d0ead6f39c22c6fb65d2d5cf5811b3f53e94f0284e62d92e
MD5 e4acf3a5552f8b23dd68884fa3b28229
BLAKE2b-256 4ed5f258c076885e9a8dbf4176174925ca8cf79298895462e6723cb53cdaee8c

See more details on using hashes here.

Provenance

The following attestation bundles were made for exarch-0.5.0-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.5.0-cp39-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for exarch-0.5.0-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 654fd31d3dcda01e35ec7e9de8818a06ce6a1c990bc6f84a9cc5bf5f45d3587f
MD5 73a6d0c475741cc2842de0bf019f36d8
BLAKE2b-256 26cfaac12f3ae4081bdd849869c7fec378457c711b2c1e166c602951e0c4309d

See more details on using hashes here.

Provenance

The following attestation bundles were made for exarch-0.5.0-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