工具链信任¶
pipguard 通过 python -m pip download 下载包。如果这个 pip 信任一个私钥已泄露的
证书颁发机构(CA),网络路径上的攻击者就能冒充 pypi.org,在 pipguard 扫描之前
把包换掉——扫描结果反而会为攻击者的代码背书。
eMudhra / emSign 事件(2026 年 10 月)¶
eMudhra 的 8 个中间 CA 私钥极弱,任何人都能为任意域名
(包括 pypi.org)签发受信任的证书。这些中间证书链接到三个根证书:
| 根证书 | 谁信任它 |
|---|---|
| emSign ECC Root CA - G3 | certifi / Mozilla、Apple、Microsoft,已在 certifi 2026.10.18/19 与 pip 26.2.2 中移除 |
| emSign Root TLS CA - G3 | Microsoft |
| AAA Certificate Services(Sectigo) | Apple、Microsoft(Mozilla 与 Chrome 已移除) |
只要 pip 用到的任何一个证书库里有这些根证书,pip 就会信任被攻破的中间证书:
- pip 自带的证书包:pip 26.2.2 之前的版本总会加载自带的 certifi,只更新操作系统没用。
- OpenSSL 系统证书库:pip 24.2+ 通过 truststore 询问系统证书库,在 Linux 上就是这个文件。
- 操作系统验证器:macOS / Windows 上 truststore 询问系统(钥匙串 / Windows 证书库)。 2026-10-22 在一台 Mac 上实测,pip 26.2.2 仍会通过这条路径接受被攻破 CA 签发的证书。
pipguard install 的处理¶
下载之前,检查即将运行的 pip 实际信任哪些证书,能修的在本次运行中修掉,然后再检查一遍:
| 发现 | pipguard 的处理 |
|---|---|
| pip 自带证书包有坏根证书(pip < 26.2.2) | 阻断,退出码 2,给出锁定哈希的修复命令(外部无法修复) |
| OpenSSL 证书库有坏根证书 | 生成一份去掉坏根证书的副本,本次运行使用它(SSL_CERT_FILE);其他 CA(如公司代理 CA)照常可用 |
| macOS 钥匙串 / Windows 证书库有坏根证书 | 让 pip 以 PIP_USE_DEPRECATED=legacy-certs 运行,只用自带的(已干净的)证书包 |
| 没有问题 | 静默继续 |
撰写本文时,GitHub ubuntu-latest runner 的系统证书库里仍然有 emSign ECC Root CA - G3,
正是这个过滤让 pip 26.2.2 在上面变得安全。
检查的是证书本身而不是 pip 版本号,所以打过补丁、改用系统证书库的发行版 pip(如 Debian)不会误报。
--require-hashes:pip 会用锁文件里的哈希校验每个下载,被替换的包会被拒绝,因此阻断降级为警告。--skip-toolchain-check:完全跳过(不推荐)。pipguard scan-feed从不安装,只给出警告。- 使用
legacy-certs时,pip 不会使用只存在于系统证书库里的 CA(例如公司 TLS 代理)。 可以用--cert/PIP_CERT提供该 CA,或更新系统去掉坏根证书。
pipguard doctor¶
显示直接运行 pip install 时信任什么,不安装任何东西:
pipguard doctor
pipguard doctor --python /usr/bin/python3 --python ~/project/.venv/bin/python
# 实测:让 pip 直接连接事件方提供的测试主机,分别以普通 pip 和 pipguard 运行的方式
pipguard doctor --online
--online 会连接 *.we-have-a-problem.com,它们使用被攻破 CA 签发的证书。结果为 rejected 才安全。
| 退出码 | 含义 |
|---|---|
0 |
普通 pip 不信任被攻破的 CA |
1 |
普通 pip 信任它们(pipguard install 可能仍受保护,见输出) |
2 |
有解释器无法检查 |
彻底修复¶
用锁定哈希的 wheel 升级 pip。有 sha256 校验,即使通过旧的有漏洞的 pip 执行也是安全的:
python -m pip install "pip @ https://files.pythonhosted.org/packages/3f/06/3e4420302363fbb71be3c7f35ce042f54bfca330e3e66b3a2e3c4cca579f/pip-26.2.2-py3-none-any.whl#sha256=fd7f4dfa8190e014013b9f08f3e973f4e4c26ffd179a204895533a7254813a70"
pip 26.2.2 需要 Python 3.10+。然后更新系统证书库(sudo apt-get install --only-upgrade ca-certificates、
brew upgrade ca-certificates、系统更新),并重新构建容器镜像:Docker 官方的
python:3.11 / python:3.12 镜像会继续带着旧 pip。
GitHub Action 会在安装 pipguard 之前自动完成 pip 升级。