Python Wheel 文件安全扫描器 — 在安装前扫描 .whl 文件中的安全问题。
受近期 Python wheel 处理相关 CVE 的启发:
零依赖。单文件。Python 3.9+。
pip-audit 检查你的包是否存在 已知 CVE。wheelaudit 检查 wheel 文件本身是否 结构上恶意 — 路径遍历、被篡改的 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
# 从标准输入读取
cat package.whl | python3 wheelaudit.py --stdin
CRITICAL(20 分):路径遍历、SUID 位、嵌入的机密信息、命令遮蔽、标准库遮蔽、RECORD 哈希篡改
HIGH(12 分):缺失 RECORD、可疑可执行文件、zip 炸弹、CRC 篡改、扩展名不匹配、符号链接、凭据收集模式
MEDIUM(6 分):反斜杠路径、缺失元数据、PEP 427 问题、子进程/网络模式
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 wheel 归档中的路径遍历 (../../../etc/crontab)
WH04 入口点遮蔽系统命令:'pip'
WH04 入口点遮蔽系统命令:'python'
WH05 嵌入的机密信息:GitHub 个人访问令牌 (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 的补充 — 它们检查已知漏洞,wheelaudit 检查 wheel 本身。
MIT
| 规则 | 严重级别 | 描述 |
|---|
| WH01 | CRITICAL | 文件名中的路径遍历(../、绝对路径、空字节) |
| 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 | 扩展名不匹配(伪装成 .py/.txt 的 ELF/PE 二进制) |
| WH15 | HIGH-MEDIUM | 符号链接和重复文件名 |
| 功能 | wheelaudit | pip-audit | safety | GuardDog |
|---|
| 零依赖 | ✅ | ❌ | ❌ | ❌ |
| 扫描 wheel 内容 | ✅ | ❌ | ❌ | ✅ |
| 路径遍历检测 | ✅ | ❌ | ❌ | ❌ |
| RECORD 完整性 | ✅ | ❌ | ❌ | ❌ |
| CVE 数据库 | ❌ | ✅ | ✅ | ❌ |
| 离线运行 | ✅ | ❌ | ❌ | ❌ |
| Python 3.9+ | ✅ | ✅ | ✅ | ✅ |