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