
Python Wheel File Security Scanner — сканер безопасности файлов .whl для проверки на уязвимости перед установкой. Обнаруживает path traversal (CVE-2026-24049), подделку RECORD, подмену команд, секреты, zip-бомбы. Без зависимостей.
Сканер безопасности Python Wheel-файлов — проверяйте файлы .whl на проблемы безопасности перед установкой.
Создан в ответ на недавние CVE в обработке Python wheel:
Ноль зависимостей. Один файл. Python 3.9+.
pip-audit проверяет, есть ли у ваших пакетов известные CVE. wheelaudit проверяет, является ли сам wheel-файл структурно вредоносным — path traversal, подделанные хеши RECORD, встроенные секреты, подмена команд, zip-бомбы и многое другое. Это разница между «известно ли, что этот пакет плохой?» и «выглядит ли этот пакет подозрительно?»
Запускайте перед pip install. Запускайте в CI. Запускайте на скачанных wheel-файлах, которым вы не доверяете.
# Просто скопируйте файл
curl -O https://raw.githubusercontent.com/kriskimmerle/wheelaudit/main/wheelaudit.py
chmod +x wheelaudit.py
# Или клонируйте репозиторий
git clone https://github.com/kriskimmerle/wheelaudit.git
cd wheelaudit
# Проверить wheel-файл
python3 wheelaudit.py package-1.0.0-py3-none-any.whl
# Проверить несколько wheel-файлов
python3 wheelaudit.py *.whl
# Проверить каталог с wheel-файлами
python3 wheelaudit.py ./wheels/
# Режим CI: выход с кодом 1, если оценка ниже порога
python3 wheelaudit.py package.whl --check --min-score 80
# JSON-вывод для интеграции с инструментами
python3 wheelaudit.py package.whl --json
# Подробный режим с деталями
python3 wheelaudit.py package.whl -v
# Фильтр по критичности
python3 wheelaudit.py package.whl --severity high
# Игнорировать конкретные правила
python3 wheelaudit.py package.whl --ignore WH11
# Чтение из stdin
cat package.whl | python3 wheelaudit.py --stdin
| Правило | Критичность | Описание |
|---|---|---|
| WH01 | CRITICAL | Path traversal в именах файлов (../, абсолютные пути, нулевые байты) |
| WH02 | CRITICAL-HIGH | Целостность файла RECORD (отсутствует, подделанные хеши, неучтённые файлы) |
| WH03 | HIGH-LOW | Подозрительные типы файлов (исполняемые, pickle, архивы, скрытые файлы) |
| WH04 | CRITICAL | Подмена команд точек входа (pip, python, sudo и т.д.) |
| WH05 | CRITICAL | Встроенные секреты (ключи API, токены, приватные ключи) |
| WH06 | CRITICAL-LOW | Проблемы с правами файлов (SUID/SGID, общедоступные для записи, исполняемые данные) |
| WH07 | HIGH-MEDIUM | Согласованность метаданных (отсутствуют METADATA/WHEEL, структурные проблемы) |
| WH08 | HIGH | Обнаружение zip-бомб (экстремальные коэффициенты сжатия, архивы сверхбольшого размера) |
| WH09 | HIGH-MEDIUM | Соответствие PEP 427 (формат имени файла, несоответствие имени/версии) |
| WH10 | CRITICAL | Конфликт пространств имён (подмена модулей стандартной библиотеки) |
| WH11 | HIGH-MEDIUM | Вредоносные паттерны кода (eval, exec, os.system, доступ к учётным данным) |
| WH12 | MEDIUM-LOW | Проблемы с файлами данных (скрипты в .data/, файлы сверхбольшого размера) |
| WH13 | HIGH | Манипуляция CRC32 (паттерн обхода CVE-2025-1889) |
| WH14 | HIGH | Несоответствие расширения (ELF/PE-бинарник, замаскированный под .py/.txt) |
| WH15 | HIGH-MEDIUM | Симлинки и дублирующиеся имена файлов |
CRITICAL (20 баллов): Path traversal, биты SUID, встроенные секреты, подмена команд, подмена стандартной библиотеки, подделка хешей RECORD
HIGH (12 баллов): Отсутствующий RECORD, подозрительные исполняемые файлы, zip-бомбы, манипуляция CRC, несоответствие расширений, симлинки, паттерны сбора учётных данных
MEDIUM (6 баллов): Пути с обратной косой чертой, отсутствующие метаданные, проблемы PEP 427, паттерны subprocess/network
LOW (2 балла): Скрытые файлы, исполняемые файлы данных, файлы большого размера
INFO (0 баллов): Легитимные нативные расширения, доступ к переменным окружения
============================================================
requests 2.32.5 — B (88/100)
============================================================
[HIGH]
WH11 Подозрительный паттерн: __import__() — динамический импорт (requests/packages.py)
Итог: 1 high
============================================================
evil-pip 99.0.0 — F (0/100)
============================================================
[CRITICAL]
WH01 Path traversal в wheel-архиве (../../../etc/crontab)
WH04 Точка входа подменяет системную команду: 'pip'
WH04 Точка входа подменяет системную команду: 'python'
WH05 Встроенный секрет: GitHub Personal Access Token (pip/__init__.py)
[HIGH]
WH02 Файл не указан в RECORD (../../../etc/crontab)
WH03 Подозрительный тип файла: .exe (pip/payload.exe)
WH11 Подозрительный паттерн: os.system() — выполнение shell-команд
WH11 Подозрительный паттерн: вызов eval() — динамическое выполнение кода
WH11 Ссылка на каталог SSH
Итог: 4 critical, 5 high, 2 medium, 2 low
{
"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
}
}
]
}
- name: Audit wheel
run: |
python3 wheelaudit.py dist/*.whl --check --min-score 80
pip download some-package --no-deps -d /tmp/wheels
python3 wheelaudit.py /tmp/wheels/*.whl --check
pip install /tmp/wheels/*.whl
wheelaudit рассматривает каждый файл .whl как недоверенный zip-архив. Он:
Никакие файлы не извлекаются на диск. Весь анализ выполняется в памяти.
| Функция | wheelaudit | pip-audit | safety | GuardDog |
|---|---|---|---|---|
| Ноль зависимостей | ✅ | ❌ | ❌ | ❌ |
| Сканирует содержимое wheel | ✅ | ❌ | ❌ | ✅ |
| Обнаружение path traversal | ✅ | ❌ | ❌ | ❌ |
| Целостность RECORD | ✅ | ❌ | ❌ | ❌ |
| База данных CVE | ❌ | ✅ | ✅ | ❌ |
| Работа в офлайн-режиме | ✅ | ❌ | ❌ | ❌ |
| Python 3.9+ | ✅ | ✅ | ✅ | ✅ |
wheelaudit дополняет pip-audit/safety — они проверяют известные уязвимости, а wheelaudit проверяет сам wheel.
MIT