5 ноября 2026 года в блоге Python Software Foundation Seth Larson рассказал, как экосистема ответила на компрометацию промежуточных CA eMudhra. Новость об инциденте вышла 20 октября. За два дня вышли правки в certifi, CPython, pip, uv, sigstore, virtualenv, conda, pixi, manylinux и gh-action-pypi-publish. 26 октября в Python Insider опубликовали срочные релизы 3.15.2, 3.14.10, 3.13.18, 3.12.16 и 3.11.18.
Если коротко для админа: браузеры закрыли дыру через CRL быстрее, а pip, uv и certifi живут со своими бандлами сертификатов. Пока эти бандлы не обновить, клиент может принять цепочку со скомпрометированным intermediate и попасть на MitM к PyPI или python.org. Патч в модуле ssl CPython (CVE-2026-115557) это last resort: даже старый pip на свежем интерпретаторе уже не должен доверять этим ключам.
Что случилось с eMudhra и emSign
Исследователи показали, что закрытые ключи восьми промежуточных CA eMudhra восстанавливаются из публичных данных. Клиент уязвим, если принимает цепочку с этими ключами и не смотрит CRL или Certificate Transparency. Тогда атакующий на пути может выдать себя за нужный HTTPS-сервис, в том числе за индекс пакетов.
В certifi лежит набор корневых CA Mozilla, без intermediate. Чтобы отключить все затронутые цепочки, из бандла убрали root «emSign Root TLS CA — G3». Advisory по certifi: GHSA-6q48-6c7w-9gw2. Браузеры успели обновить отзыв без обязательного обновления приложения. У pip и uv свой store, поэтому без обновления софта они оставались открытыми.
Цепочка certifi, Requests, pip и ensurepip
Здесь важна привычная связка поставки. certifi нужен, чтобы свежий venv вообще мог ходить на PyPI по HTTPS. pip бандлит зависимости, среди них Requests, а Requests тянет certifi. CPython бандлит pip через ensurepip, поэтому новый python -m venv получает тот pip, который лежит в интерпретаторе.
Отсюда три обязательных звена: обновить certifi там, где он в зависимостях приложения; обновить pip в каждом уже живом venv (системный или «голый» pip свой бандл сам не подтянет из вашего requirements); обновить сам интерпретатор, чтобы ensurepip и denylist в ssl были свежими. Для старых веток Python отдельного вечного pip внутри ensurepip нет: совместимость мешает просто подложить новый pip во все прошлые релизы, поэтому denylist в ssl и сделали last resort.
Какие версии ставить
Ориентир по гайдам PSF / pydevtools и релизам:
- CPython: 3.11.18, 3.12.16, 3.13.18, 3.14.10 или 3.15.2 (и новее в своей ветке)
- pip: 26.2.2
- certifi: 2026.10.19
- uv: advisory закрыт с 0.13.4; для полного покрытия берите 0.13.6 (там же подтягиваются пропатченные managed-сборки CPython)
Python 3.15.2 и 3.14.10 идут с бинарными установщиками. 3.13.18, 3.12.16 и 3.11.18 — source-only security releases: на macOS/Windows либо собирайте из исходников, либо берите пропатченный билд у дистрибьютора вроде uv, либо переходите на 3.14/3.15. Python 3.10 и старше в EOL и этого фикса не получили.
CVE-2026-115557 затрагивает CPython ниже 3.11.18, ветки 3.12.0-3.12.15, 3.13.0-3.13.17, 3.14.0-3.14.9, 3.15.0-3.15.1 и пререлизы 3.16 до появления фикса в changelog. В тех же срочных релизах закрыли ещё CVE-2026-114583 в tarfile.tar_filter (отклонение ссылок, которые подменяют цель) и баг с cookie отрицательной version в http.cookiejar.
uv 0.13.5 и что сделать в CI
В uv 0.13.5 (21 октября) обновили managed CPython через python-build-standalone 20261021 и отвергли скомпрометированные ключи через rustls-webpki 0.103.16. Ранее 0.13.4 уже выкинул затронутый root из собственного store uv. После апгрейда uv выполните uv python upgrade: старые pinned patch-версии интерпретатора сами не переедут. В уже созданных venv pip всё равно обновляйте отдельно.
Для контейнеров и CI: обновите пины инструментов и зависимостей, стяните свежие base image, пересоберите без кэша слоёв и задеплойте новые образы. Обновление только certifi в приложении не заменяет бандл внутри pip. Дистрибутивный pip обновляйте пакетами своего дистрибутива.
python -m pip install --upgrade pip==26.2.2 certifi==2026.10.19 # или в каждом venv: # python -m pip install -U 'pip==26.2.2' 'certifi==2026.10.19'
Обновите интерпретатор и pip/uv во всех окружениях, пересоберите контейнеры и CI-образы. Denylist в ssl закрывает MitM на пути к апгрейду pip, но нормальный порядок всё равно такой: свежий CPython, свежий pip или uv, свежий certifi в зависимостях приложения.
