eMudhra事件震动Python:pip和certifi须立即更新
印度证书机构eMudhra私钥泄露事件对Python生态的冲击远大于浏览器。由于pip自带证书列表且无法关闭,即使操作系统已更新,旧版pip仍会信任伪造证书。Python核心开发者要求用户立即更新pip、certifi、uv和conda。
印度证书机构eMudhra的八张中间证书私钥可被任何人还原一事,给Python用户带来的麻烦最大。根据CPython核心开发者Seth Michael Larson于10月20日在Python官方讨论区发布并置顶的公告帖,Python用户需要立即更新部分软件包,并在关闭层缓存的情况下重新构建容器镜像,否则连接python.org和pypi.org的工具可能面临中间人(MITM)攻击。该帖两天内浏览量超过9万次,回复数十条。
事件回顾
eMudhra于2025年4月生成的八张中间证书,其私钥是远小于正常值的数字,其中一个仅为4。利用这些私钥,任何人都能为任意网站制作看似有效的伪造HTTPS证书。浏览器于10月17日晚拦截了这些证书,Mozilla和谷歌移除了对eMudhra ECC根证书的信任。但其中部分中间证书还由另一个根证书Comodo/Sectigo AAA Certificate Services交叉签名,而旧版证书列表中仍包含这个根证书。正是这一点让Python工具陷入麻烦。
为何Python受影响更严重
浏览器和操作系统自行分发吊销列表,而在Python生态中,许多工具自带受信任的根证书。长期参与Python安全工作的Christian Heimes在讨论中解释说,pip总是从其内置的certifi副本加载受信任证书,且没有受支持的关闭方式;指定自己的证书文件也无法停用旧列表。因此,所有早于26.2.2的pip版本都会继续信任这些泄露的中间证书。Heimes认为,更新pip是唯一可靠的修复方法。
这意味着在执行pip install时,中间人可以用伪造证书冒充PyPI并提供恶意软件包。因此官方帖子建议通过固定校验值(hash)的直接链接安装pip,即使遭遇中间人攻击也能确保安装正确的文件。请只从官方讨论帖中复制该命令及其校验值,不要从二手来源复制。
需要更新的内容
官方帖子及相关安全公告给出的最低安全版本:
- certifi 2026.10.19(公告写的是2026.10.18,帖子推荐2026.10.19;该公告评级为严重)
- pip 26.2.2
- uv 0.13.4(uv自己的公告评级为高危)
- conda 26.9.4;conda-forge上的ca-certificates 2026.10.19,Anaconda频道上的2026.10.20
- pixi 0.82.1、sigstore 4.5.1
- 向PyPI上传软件包的GitHub Action pypi-publish 1.14.3;wheel构建工具cibuildwheel 4.3.3,Python 3.9上的pip需4.3.4
- 捆绑修复版pip的Python版本:3.15.1、3.14.9和3.13.17
帖子还为uv用户提供了另一种方式:设置UV_SYSTEM_CERTS=true可让uv使用操作系统证书。pip没有这样的设置。
各操作系统情况
- macOS(python.org安装包):据帖子介绍,certifi随该安装包一同提供,需要单独更新。
- macOS(系统自带Python):据事件页面,macOS已拦截泄露的证书,但系统自带的python3、curl和git使用的是尚未更新的/etc/ssl/cert.pem,系统pip也使用自己的旧列表。
- Windows:微软通过自动更新下发了拦截。未收到更新的机器可使用单独的脚本,但不建议在企业托管设备上使用。
- Linux:取决于发行版的ca-certificates软件包,Ubuntu、Debian、Fedora、Alpine、Arch等均已发布更新。Debian对自己的pip软件包做了修改,使其使用系统证书。
Docker、CI与锁文件
讨论中有用户报告,官方python:3.15-slim Docker镜像自带pip 26.2.1,因此并不安全。Python核心开发者回应称,这些“官方”镜像是Docker的官方镜像,而非Python项目的,由另一团队维护。Python指导委员会成员Barry Warsaw写道,半官方的CI镜像会自动更新到最新版本,因此Python 3.13至3.15应当是安全的,而3.16在alpha 2发布前并不完全安全。
用锁文件或固定版本管理依赖的项目,如果固定了旧版certifi,就不会自动修复。使用依赖冷却期(延迟采用新版本)设置的项目在更新之前同样存在风险。这也是要求在无缓存情况下重建容器镜像的原因:残留在旧镜像层中的pip和certifi即使重建镜像也可能不会改变。
争论焦点:3.11和3.12
讨论中最激烈的部分围绕只接收安全修复的Python 3.11和3.12。这些分支的安全版本通常不会更新捆绑的pip。发布经理Hugo van Kemenade解释说,安全版本通常不更新pip;指导委员会成员Thomas Wouters也指出,pip没有与新功能和不兼容变更分开的安全版本。用户认为使用这些版本的人默认将处于不安全状态,并要求为旧pip分支发布修复版本;pip维护者表示无法维护旧分支。
版主Łukasz Langa宣布,发布经理更倾向于采用有针对性的修复,而不是整体升级pip,并将很快公布细节。作为其中一部分,Heimes提出在CPython的ssl模块中加入已知泄露密钥的阻止列表。这一提议本身也引发争论:部分核心开发者强调该列表并不是安全边界,不应让“升级Python”成为应对今后每次事件的固定答案;Heimes则表示,只有在受信任的根证书或中间证书泄露时才会更新该列表,它被设计为最后一道防线。Node.js也加入了类似的阻止列表。
如何检查
- 用
python -m pip --version检查pip版本,用python -m certifi查看certifi的位置。 - 用curl连接事件页面上的测试地址,出现证书错误说明你的工具不信任这些泄露的证书。
- 不要遗漏电脑上的每一个虚拟环境(venv),每个环境中都可能有独立的pip和certifi副本。
以上信息来自Python官方讨论帖、certifi、uv和conda的安全公告以及报告该事件的研究人员的事件页面。需要注意的是,这些泄露的密钥自2025年4月起实际上就可被猜出,期间是否遭到滥用尚不清楚。与浏览器不同,大多数Python工具不检查证书透明度日志,因此更新运行在服务器、CI流水线和旧Docker镜像中的Python代码比更新浏览器更加重要。建议同时关注独立安全研究人员的评估,从不同角度了解情况。