🐛 fix(periodic-update): refuse unverified HTTPS to PyPI by default#3122
Merged
Conversation
53ae5cd to
1b440c9
Compare
When the verified HTTPS request to ``https://pypi.org/pypi/<dist>/json`` failed, the periodic update retried with an unverified SSL context and used whatever it got back. The original reasoning was that the metadata is not sensitive, but the response drives the "latest wheel" decision, so a network-level attacker with a TLS handshake in the middle can quietly pin virtualenv to an older version and suppress security updates. Skip the fallback by default and abort the lookup instead. Hosts with broken trust stores that need the old behaviour can set ``VIRTUALENV_PERIODIC_UPDATE_INSECURE=1`` as an explicit escape hatch, logged at WARNING so it is visible in CI output.
1b440c9 to
e40ca49
Compare
rahuldevikar
approved these changes
Apr 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Security hardening. When the verified HTTPS request to
https://pypi.org/pypi/<dist>/jsonfailed, the periodic update retried the request with an unverified SSL context and used whatever came back. The original comment justified this with 'the information we request is not sensitive', but the metadata drives the decision about which wheel version virtualenv considers 'up to date'. 🔒 A network-level attacker that can break the handshake can then pin virtualenv to an older seed wheel and silently suppress security updates.The fallback is now skipped by default. A failed verified request logs the error and returns
None, which the periodic update path already handles gracefully — no wheel bump happens and the run continues. Hosts with genuinely broken trust stores can opt back in by settingVIRTUALENV_PERIODIC_UPDATE_INSECURE=1, which is logged at WARNING so it shows up in CI output. The env var is documented indocs/how-to/usage.rstnext to the existing override knobs.