Share
## https://sploitus.com/exploit?id=CBDD1622-7DA5-571A-B928-BD85C2201B95
# wheelaudit
**Python Wheel File Security Scanner** โ scan `.whl` files for security issues before installation.
Motivated by recent CVEs in Python wheel handling:
- **CVE-2026-24049**: Path traversal in wheel unpack allows permission manipulation of system files
- **CVE-2026-1703**: Path traversal when pip installs wheel archives
- **Google GHSA-w97x-xxj5-gpjx**: Zip parser differential vulnerability in Python wheels
Zero dependencies. Single file. Python 3.9+.
## Why?
`pip-audit` checks if your packages have *known CVEs*. `wheelaudit` checks if a wheel file itself is *structurally malicious* โ path traversal, tampered RECORD hashes, embedded secrets, command shadowing, zip bombs, and more. It's the difference between "is this package known-bad?" and "does this package look bad?"
Run it before `pip install`. Run it in CI. Run it on downloaded wheels you don't trust.
## Installation
```bash
# Just copy the file
curl -O https://raw.githubusercontent.com/kriskimmerle/wheelaudit/main/wheelaudit.py
chmod +x wheelaudit.py
# Or clone the repo
git clone https://github.com/kriskimmerle/wheelaudit.git
cd wheelaudit
```
## Usage
```bash
# Scan a wheel file
python3 wheelaudit.py package-1.0.0-py3-none-any.whl
# Scan multiple wheels
python3 wheelaudit.py *.whl
# Scan a directory of wheels
python3 wheelaudit.py ./wheels/
# CI mode: exit 1 if score below threshold
python3 wheelaudit.py package.whl --check --min-score 80
# JSON output for tooling integration
python3 wheelaudit.py package.whl --json
# Verbose mode with details
python3 wheelaudit.py package.whl -v
# Filter by severity
python3 wheelaudit.py package.whl --severity high
# Ignore specific rules
python3 wheelaudit.py package.whl --ignore WH11
# Read from stdin
cat package.whl | python3 wheelaudit.py --stdin
```
## Rules
| Rule | Severity | Description |
|------|----------|-------------|
| **WH01** | CRITICAL | Path traversal in filenames (`../`, absolute paths, null bytes) |
| **WH02** | CRITICAL-HIGH | RECORD file integrity (missing, tampered hashes, unlisted files) |
| **WH03** | HIGH-LOW | Suspicious file types (executables, pickle, archives, hidden files) |
| **WH04** | CRITICAL | Entry point command shadowing (`pip`, `python`, `sudo`, etc.) |
| **WH05** | CRITICAL | Embedded secrets (API keys, tokens, private keys) |
| **WH06** | CRITICAL-LOW | File permission issues (SUID/SGID, world-writable, executable data) |
| **WH07** | HIGH-MEDIUM | Metadata consistency (missing METADATA/WHEEL, structural issues) |
| **WH08** | HIGH | Zip bomb detection (extreme compression ratios, oversized archives) |
| **WH09** | HIGH-MEDIUM | PEP 427 compliance (filename format, name/version mismatch) |
| **WH10** | CRITICAL | Namespace collision (stdlib module shadowing) |
| **WH11** | HIGH-MEDIUM | Malicious code patterns (eval, exec, os.system, credential access) |
| **WH12** | MEDIUM-LOW | Data file issues (scripts in .data/, oversized files) |
| **WH13** | HIGH | CRC32 manipulation (CVE-2025-1889 bypass pattern) |
| **WH14** | HIGH | Extension mismatch (ELF/PE binary disguised as .py/.txt) |
| **WH15** | HIGH-MEDIUM | Symlinks and duplicate filenames |
### 15 rules, 5 severity levels
**CRITICAL** (20 points): Path traversal, SUID bits, embedded secrets, command shadowing, stdlib shadowing, RECORD hash tampering
**HIGH** (12 points): Missing RECORD, suspicious executables, zip bombs, CRC manipulation, extension mismatch, symlinks, credential harvesting patterns
**MEDIUM** (6 points): Backslash paths, missing metadata, PEP 427 issues, subprocess/network patterns
**LOW** (2 points): Hidden files, executable data files, large files
**INFO** (0 points): Legitimate native extensions, environment variable access
## Example Output
### Clean wheel (requests 2.32.5)
```
============================================================
requests 2.32.5 โ B (88/100)
============================================================
[HIGH]
WH11 Suspicious pattern: __import__() โ dynamic import (requests/packages.py)
Summary: 1 high
```
### Malicious wheel
```
============================================================
evil-pip 99.0.0 โ F (0/100)
============================================================
[CRITICAL]
WH01 Path traversal in wheel archive (../../../etc/crontab)
WH04 Entry point shadows system command: 'pip'
WH04 Entry point shadows system command: 'python'
WH05 Embedded secret: GitHub Personal Access Token (pip/__init__.py)
[HIGH]
WH02 File not listed in RECORD (../../../etc/crontab)
WH03 Suspicious file type: .exe (pip/payload.exe)
WH11 Suspicious pattern: os.system() โ shell command execution
WH11 Suspicious pattern: eval() call โ dynamic code execution
WH11 Suspicious pattern: SSH directory reference
Summary: 4 critical, 5 high, 2 medium, 2 low
```
## JSON Output
```json
{
"version": "0.1.0",
"results": [
{
"path": "package-1.0.0-py3-none-any.whl",
"score": 88,
"grade": "B",
"metadata": {
"name": "package",
"version": "1.0.0",
"file_count": 15,
"total_uncompressed_bytes": 45000
},
"findings": [
{
"rule": "WH11",
"severity": "high",
"message": "Suspicious pattern: __import__() โ dynamic import",
"file": "package/compat.py"
}
],
"summary": {
"high": 1
}
}
]
}
```
## CI Integration
### GitHub Actions
```yaml
- name: Audit wheel
run: |
python3 wheelaudit.py dist/*.whl --check --min-score 80
```
### Pre-install gate
```bash
pip download some-package --no-deps -d /tmp/wheels
python3 wheelaudit.py /tmp/wheels/*.whl --check
pip install /tmp/wheels/*.whl
```
## How It Works
wheelaudit treats every `.whl` file as an untrusted zip archive. It:
1. **Parses zip metadata** without extracting (safe inspection)
2. **Checks archive structure** for path traversal, symlinks, duplicates
3. **Verifies RECORD integrity** โ hashes and file lists
4. **Inspects file types** โ executables, binaries, hidden files
5. **Scans text content** โ secrets, malicious code patterns
6. **Validates PEP 427 compliance** โ filename, metadata, structure
7. **Detects known attack patterns** โ CVE-2026-24049, CRC manipulation, parser differentials
No files are extracted to disk. All analysis happens in memory.
## Comparison
| Feature | wheelaudit | pip-audit | safety | GuardDog |
|---------|-----------|-----------|--------|----------|
| Zero deps | โ
| โ | โ | โ |
| Scans wheel contents | โ
| โ | โ | โ
|
| Path traversal detection | โ
| โ | โ | โ |
| RECORD integrity | โ
| โ | โ | โ |
| CVE database | โ | โ
| โ
| โ |
| Offline operation | โ
| โ | โ | โ |
| Python 3.9+ | โ
| โ
| โ
| โ
|
wheelaudit complements pip-audit/safety โ they check known vulnerabilities, wheelaudit checks the wheel itself.
## License
MIT