A comment on it from Christian Helms adds: Just to stress one point: users must update pip to >= 26.2.2.
pip always loads the CA certificates from its vendored certifi in addition to the system trust store, and there is no supported way to disable this. REQUESTSCABUNDLE / --cert only add CAs; truststore is used “in addition to certifi” by design. As a result, any pip < 26.2.2 will keep trusting the compromised intermediate CAs regardless of the system trust store, so distrusting them at the OS level is not enough. The discuss.python.org conversation on that issue has long since moved on, so asking here:
The macOS remediation advice on the official vuln page at https://emudhra.we-have-a-problem.com/#macos-curl lists remediation instructions which it is claimed address this, with instructions to set a PIPCERT environment variable in a sitecustomize.py file. The built-in pip3, and the pip in virtual environments created from the built-in python3, use their own outdated copy of the roots instead. To make them use the fixed system file, run:
F="$(/usr/bin/python3 -c 'import sysconfig; print(sysconfig.getpath("stdlib"))')/sitecustomize.py" && echo 'import os; os.environ.setdefault("PIPCERT", "/etc/ssl/cert.pem")' | sudo tee -a "$F" > /dev/null && sudo chmod 644 "$F"
I'm finding it a bit tricky to figure out a reproducible test case which would exercise this, so I haven't done more testing myself, but—does this actually work? Or is upgrading pip to >= 26.2.2 the only solution? (Or, now that pip > 26.2.2 is out, is upgrading the better solution, and I should go file a PR against the site to update its guidance.)
(Incidentally, the latest macOS updates do NOT include an updated /etc/ssl/cert.pem, and do clobber any manual changes you or your IT department may have made to /etc/ssl/cert.pem, so any manual mitigations you have applied to remove the AAA Certificate Services and emSign ECC Root CA - G3 certs DO need to be reapplied.)
Best, - Kevin
On Thu, Oct 22, 2026 at 4:43 PM Alan Coopersmith <alan.coopersmith () oracle com> wrote: https://discuss.python.org/t/information-for-python-users-regarding-emudhra-emsign-ca-certificate-security-incident/109576 has this statement from Seth Michael Larson: A security incident affecting eMudhra intermediate certificates has required removing the emSign root CA certificate from CA bundles such as “certifi”. It’s important to immediately upgrade the software packages below to at least the versions specified and rebuild container images with layer caching disabled to fetch the latest system certificates. Failure to do so could result in monster-in-the-middle (MITM) attacks against TLS clients, including python.org and pypi.org .
certifi 2026.10.19 (1) pip 26.2.2 uv 0.13.4 sigstore 4.5.1 conda 26.9.4 pixi 0.82.1
(1): Advisory mentions 2026.10.18, but 2026.10.19 is recommended for compatibility with unaffected emSign root certificates.
For all existing virtual environments on your system, please upgrade pip and uv to the latest versions. You can update pip securely by running the following command and then use this secure pip installation to upgrade certifi and uv:
python -m pip install "pip @ https://files.pythonhosted.org/packages/3f/06/3e4420302363fbb71be3c7f35ce042f54bfca330e3e66b3a2e3c4cca579f/pip-26.2.2-py3-none-any.whl#sha256=fd7f4dfa8190e014013b9f08f3e973f4e4c26ffd179a204895533a7254813a70";
Note that the certifi CA bundle is included in the macOS installation of Python from python.org. To upgrade certificates for this installation and pip itself, run the command below like so:
/Library/Frameworks/Python.framework/Versions/3.15/bin/python3.15 -m pip install "pip @ https://files.pythonhosted.org/packages/3f/06/3e4420302363fbb71be3c7f35ce042f54bfca330e3e66b3a2e3c4cca579f/pip-26.2.2-py3-none-any.whl#sha256=fd7f4dfa8190e014013b9f08f3e973f4e4c26ffd179a204895533a7254813a70"; /Library/Frameworks/Python.framework/Versions/3.15/bin/python3.15 -m pip install --upgrade certifi /Library/Frameworks/PythonT.framework/Versions/3.15/bin/python3.15t -m pip install "pip @ https://files.pythonhosted.org/packages/3f/06/3e4420302363fbb71be3c7f35ce042f54bfca330e3e66b3a2e3c4cca579f/pip-26.2.2-py3-none-any.whl#sha256=fd7f4dfa8190e014013b9f08f3e973f4e4c26ffd179a204895533a7254813a70";
This topic will be updated as more information is made available. A comment on it from Christian Helms adds: Just to stress one point: users must update pip to >= 26.2.2.
pip always loads the CA certificates from its vendored certifi in addition to the system trust store, and there is no supported way to disable this. REQUESTSCABUNDLE / --cert only add CAs; truststore is used “in addition to certifi” by design. As a result, any pip < 26.2.2 will keep trusting the compromised intermediate CAs regardless of the system trust store, so distrusting them at the OS level is not enough.
uv users can block the bad certs in their system trust store and UVSYSTEMCERTS=true. That does not work with pip. Updating pip is the only reliable fix. See Switch to using truststore only by default (currently mixed certifi + truststore) · Issue #14374 · pypa/pip · GitHub
PS: The ‘security incident’ is a bad private key. An elliptic key with private key value d=4 is not secure… All 8 eMudhra CAs had private keys with d < 256.
-- Kevin Riggle - Principal, Complex Systems Group LLC he/him • Brooklyn, NY, USA • Eastern Time https://complexsystems.group • https://calendly.com/kevinriggle/coffee
The Python ecosystem is pushing towards using https://pypi.org/project/truststore/ rather than solutions like certifi. This incident will likely help increase the priority of that transition.
On Fri, 2026-10-23 at 00:07 +0300, Valtteri Vuorikoski wrote: Having spent the day whacking this particular molehill, my strong opinion is that these packages (minus certifi) should stop vendoring roots immediately.
Users should install their distro's ca-certificates package or similar. If that is completely impossible for whatever reason, offer an option to use certifi (which should be a dependency, not vendored) - but the system trust store should be the default source of truth.
This sort of easter egg hiding to serve users with broken installations reduces the security of everyone else.
(Missing from the quoted list: botocore also includes a vendored copy. I haven't checked how it's used.)
-valtteri
On Thu, Oct 22, 2026 at 01:43:08PM -0700, Alan Coopersmith wrote: https://discuss.python.org/t/information-for-python-users-regarding-emudhra-emsign-ca-certificate-security-incident/109576 has this statement from Seth Michael Larson: A security incident affecting eMudhra intermediate certificates has required removing the emSign root CA certificate from CA bundles such as “certifi”. It’s important to immediately upgrade the software packages below to at least the versions specified and rebuild container images with layer caching disabled to fetch the latest system certificates. Failure to do so could result in monster-in-the-middle (MITM) attacks against TLS clients, including python.org and pypi.org .
certifi 2026.10.19 (1) pip 26.2.2 uv 0.13.4 sigstore 4.5.1 conda 26.9.4 pixi 0.82.1
Having spent the day whacking this particular molehill, my strong opinion is that these packages (minus certifi) should stop vendoring roots immediately.
Users should install their distro's ca-certificates package or similar. If that is completely impossible for whatever reason, offer an option to use certifi (which should be a dependency, not vendored) - but the system trust store should be the default source of truth.
This sort of easter egg hiding to serve users with broken installations reduces the security of everyone else.
(Missing from the quoted list: botocore also includes a vendored copy. I haven't checked how it's used.)
-valtteri
On Thu, Oct 22, 2026 at 01:43:08PM -0700, Alan Coopersmith wrote: https://discuss.python.org/t/information-for-python-users-regarding-emudhra-emsign-ca-certificate-security-incident/109576 has this statement from Seth Michael Larson: A security incident affecting eMudhra intermediate certificates has required removing the emSign root CA certificate from CA bundles such as “certifi”. It’s important to immediately upgrade the software packages below to at least the versions specified and rebuild container images with layer caching disabled to fetch the latest system certificates. Failure to do so could result in monster-in-the-middle (MITM) attacks against TLS clients, including python.org and pypi.org .
certifi 2026.10.19 (1) pip 26.2.2 uv 0.13.4 sigstore 4.5.1 conda 26.9.4 pixi 0.82.1
https://discuss.python.org/t/information-for-python-users-regarding-emudhra-emsign-ca-certificate-security-incident/109576 has this statement from Seth Michael Larson: A security incident affecting eMudhra intermediate certificates has required removing the emSign root CA certificate from CA bundles such as “certifi”. It’s important to immediately upgrade the software packages below to at least the versions specified and rebuild container images with layer caching disabled to fetch the latest system certificates. Failure to do so could result in monster-in-the-middle (MITM) attacks against TLS clients, including python.org and pypi.org .
certifi 2026.10.19 (1) pip 26.2.2 uv 0.13.4 sigstore 4.5.1 conda 26.9.4 pixi 0.82.1
(1): Advisory mentions 2026.10.18, but 2026.10.19 is recommended for compatibility with unaffected emSign root certificates.
For all existing virtual environments on your system, please upgrade pip and uv to the latest versions. You can update pip securely by running the following command and then use this secure pip installation to upgrade certifi and uv:
python -m pip install "pip @ https://files.pythonhosted.org/packages/3f/06/3e4420302363fbb71be3c7f35ce042f54bfca330e3e66b3a2e3c4cca579f/pip-26.2.2-py3-none-any.whl#sha256=fd7f4dfa8190e014013b9f08f3e973f4e4c26ffd179a204895533a7254813a70";
Note that the certifi CA bundle is included in the macOS installation of Python from python.org. To upgrade certificates for this installation and pip itself, run the command below like so:
/Library/Frameworks/Python.framework/Versions/3.15/bin/python3.15 -m pip install "pip @ https://files.pythonhosted.org/packages/3f/06/3e4420302363fbb71be3c7f35ce042f54bfca330e3e66b3a2e3c4cca579f/pip-26.2.2-py3-none-any.whl#sha256=fd7f4dfa8190e014013b9f08f3e973f4e4c26ffd179a204895533a7254813a70"; /Library/Frameworks/Python.framework/Versions/3.15/bin/python3.15 -m pip install --upgrade certifi /Library/Frameworks/PythonT.framework/Versions/3.15/bin/python3.15t -m pip install "pip @ https://files.pythonhosted.org/packages/3f/06/3e4420302363fbb71be3c7f35ce042f54bfca330e3e66b3a2e3c4cca579f/pip-26.2.2-py3-none-any.whl#sha256=fd7f4dfa8190e014013b9f08f3e973f4e4c26ffd179a204895533a7254813a70";
This topic will be updated as more information is made available. A comment on it from Christian Helms adds: Just to stress one point: users must update pip to >= 26.2.2.
pip always loads the CA certificates from its vendored certifi in addition to the system trust store, and there is no supported way to disable this. REQUESTSCABUNDLE / --cert only add CAs; truststore is used “in addition to certifi” by design. As a result, any pip < 26.2.2 will keep trusting the compromised intermediate CAs regardless of the system trust store, so distrusting them at the OS level is not enough.
uv users can block the bad certs in their system trust store and UVSYSTEMCERTS=true. That does not work with pip. Updating pip is the only reliable fix. See Switch to using truststore only by default (currently mixed certifi + truststore) · Issue #14374 · pypa/pip · GitHub
PS: The ‘security incident’ is a bad private key. An elliptic key with private key value d=4 is not secure… All 8 eMudhra CAs had private keys with d < 256.
Astral uv before 0.8.22 contains a path traversal vulnerability in source distribution (sdist) tar extraction that allows a specially crafted sequence of symlinks to redirect file writes outside the intended extraction prefix. Attackers can publish a malicious sdist that, when installed by a victim, writes arbitrary files to filesystem locations outside the installation prefix.
uv before 0.11.15 contains a path traversal vulnerability that allows malicious wheels to write files outside the scripts directory via crafted consolescripts or guiscripts entry point names. Attackers who induce users to install a malicious wheel can place executables in PATH directories, shadowing or overwriting existing binaries for code execution.
Impact
In versions of uv from 0.12.7 to 0.12.18 on Windows, uv could be induced into writing a file outside of the installation prefix during wheel installation.
A malicious wheel could use this to place an executable outside of the intended environment, including in a directory already present on the user's PATH.
This vulnerability only affects Windows hosts; no other platforms are affected.
Patches
uv 0.12.18 and newer address this vulnerability. Users are encouraged to upgrade to 0.12.18.
Workarounds
There is no workaround other than upgrading to uv 0.12.18.
Impact
In versions 0.9.5 and earlier of uv, ZIP archives were handled in a manner that enabled two parsing differentials against other components of the Python packaging ecosystem:
1. Central directory entries in a ZIP archive can contain comment fields. However, uv would assume that these fields were not present, since they aren't widely used. Consequently, a ZIP archive could be constructed where uv would interpret the contents of a central directory comment field as ZIP control structures (such as a new central directory entry), rather than skipping over them. 2. Both local file entries and central directory entries contain filename fields, which are used to place archive members on disk. These fields are arbitrary sequences of bytes, and may therefore be invalid or ambiguous. For example, they may contain ASCII null bytes, in which case different ZIP extractors behave differently: Python's zipfile module truncates the filename at the first null, while uv would skip (not extract) any archive members whose filenames contained nulls. Because of this difference, a ZIP archive could be constructed that would extract differently across different Python package installers.
In both cases, the outcome is that an attacker may be able to produce a ZIP with a consistent digest that expands differently with different Python package installers.
Like with GHSA-8qf3-x8v5-2pj8, the impact of these differentials is limited by a number of factors:
- To be compromised via this vulnerability, user interaction of some sort is required. In particular, the user must run uv pip install $package or similar with an attacker-controlled $package. When using wheel distributions, installation of the malicious package is not sufficient for execution of malicious code, the vicim would need to perform a separate invocation, e.g., python -c "import $package". - If a ZIP-based source distribution (which are less common than tarball source distributions), is encountered, malicious code can be executed during package resolution or installation. uv may invoke the malicious code when building the source distribution into a wheel.
Patches
Versions 0.9.6 and newer of uv address both of the parser differentials above, by properly handling comments in central directory entries and by refusing to process ZIPs that contain filename fields that are unlikely to be interpreted consistently across other ZIP parser implementations.
Workarounds
Users are advised to upgrade to 0.9.6 or newer to address this advisory.
Most users should experience no breaking changes as a result of the patch above. However, users who do experience breakage should carefully review their distributions for signs of malicious intent. Users may choose to set UVINSECURENOZIPVALIDATION=1 to revert to the previous behavior.
Attribution
This vulnerability was disclosed by Caleb Brown (Google).
Impact
In versions 0.9.5 and earlier of uv, ZIP archives were handled in a manner that enabled two parsing differentials against other components of the Python packaging ecosystem:
1. Central directory entries in a ZIP archive can contain comment fields. However, uv would assume that these fields were not present, since they aren't widely used. Consequently, a ZIP archive could be constructed where uv would interpret the contents of a central directory comment field as ZIP control structures (such as a new central directory entry), rather than skipping over them. 2. Both local file entries and central directory entries contain filename fields, which are used to place archive members on disk. These fields are arbitrary sequences of bytes, and may therefore be invalid or ambiguous. For example, they may contain ASCII null bytes, in which case different ZIP extractors behave differently: Python's zipfile module truncates the filename at the first null, while uv would skip (not extract) any archive members whose filenames contained nulls. Because of this difference, a ZIP archive could be constructed that would extract differently across different Python package installers.
In both cases, the outcome is that an attacker may be able to produce a ZIP with a consistent digest that expands differently with different Python package installers.
Like with GHSA-8qf3-x8v5-2pj8, the impact of these differentials is limited by a number of factors:
- To be compromised via this vulnerability, user interaction of some sort is required. In particular, the user must run uv pip install $package or similar with an attacker-controlled $package. When using wheel distributions, installation of the malicious package is not sufficient for execution of malicious code, the vicim would need to perform a separate invocation, e.g., python -c "import $package". - If a ZIP-based source distribution (which are less common than tarball source distributions), is encountered, malicious code can be executed during package resolution or installation. uv may invoke the malicious code when building the source distribution into a wheel.
Patches
Versions 0.9.6 and newer of uv address both of the parser differentials above, by properly handling comments in central directory entries and by refusing to process ZIPs that contain filename fields that are unlikely to be interpreted consistently across other ZIP parser implementations.
Workarounds
Users are advised to upgrade to 0.9.6 or newer to address this advisory.
Most users should experience no breaking changes as a result of the patch above. However, users who do experience breakage should carefully review their distributions for signs of malicious intent. Users may choose to set UVINSECURENOZIPVALIDATION=1 to revert to the previous behavior.
Attribution
This vulnerability was disclosed by Caleb Brown (Google).