Repository navigation
SECURITY: httpie: hash-lock the dependency closure with certifi 2026.10.19 (CVE-2026-111943) - #952
Merged
Conversation
…9 (CVE-2026-111943) build.sh let pip resolve httpie's deps from PyPI at build time with no pins, so requests' certifi bundle was whatever PyPI served that day and could still trust emSign ECC Root CA - G3 (eMudhra intermediate key compromise, Mozilla bug 2083449). Install the closure from a requirements.lock (version + sha256 per distribution, wheels only, --no-deps), with certifi 2026.10.19, the first release without G3. pip check guards the closure; the build fails if certifi still contains G3; add an offline standalone regression test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
Warning Review limit reached
This review includes 2 billable files and costs up to $0.50.
Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing. Or wait 2 minutes for your next included review. View limit details
Comment |
jtnkminimal
approved these changes
Oct 20, 2026
This was referenced Oct 26, 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.
httpie's
build.shranpip3 install --root "$OUTPUT_DIR" .with no pins, so pip resolved the whole dependency tree from PyPI at build time. Thecertifithatrequestsverifies TLS against was therefore whatever PyPI served on the day of the build. That breaks reproducibility, and it meant the CA bundle could not be held at a fixed release. Any build up to 2026.07.22 shipped emSign ECC Root CA - G3 (SHA-25686A1ECBA089C4A8D3BBE2734C612BA341D813E043CF9E8A862CD5C57A36BBE6B). Mozilla distrusted that root after eMudhra's intermediate key was compromised (CVE-2026-111943, Mozilla bug 2083449).Change
requirements.lock: the full runtime closure, 14 distributions. Each entry pins one version and the sha256 of every file for that version, so a single lock serves both arches. It was generated withuv pip compile --only-binary :all: --generate-hashes, which resolves from wheel metadata only, for Python 3.14 manylinux_2_28. The x86_64 and aarch64 outputs are byte-identical.certifi==2026.10.19is the first certifi without G3. 2026.10.18 dropped all four emSign roots, and .19 restored G1/C1/C3 while keeping G3 out. I checked this by fingerprint: 2026.06.17 and 2026.07.22 contain G3, and 2026.10.19 has 120 roots without it.--exclude-newer 2026-10-06, so no same-day upload enters the lock. certifi is the one deliberate exception. As a resultsetuptoolsis 84.0.0, not today's 84.2.1, andmultidictis 7.0.0, not 7.1.0.httpie(installed from the pinned source tarball) andpipare left out. httpie requires pip forhttpie cli plugins, and the python runtime dep's pip satisfies it, so a second copy under--rootwould shadow it. The header ofrequirements.lockdocuments both exclusions and how to regenerate the lock.pip3 install --require-hashes --no-deps --only-binary :all: -r requirements.lock, then installs httpie with--no-deps. Build isolation stays on for httpie's own setup.py build, as before. That build backend is fetched unpinned, but it only builds httpie's wheel and does not ship.pip checkover the installed tree (PYTHONPATH=<site-packages>), so a dependency missing from the lock fails the build instead of failing at import time.certifi/cacert.pemcontains G3. The needle is a line of G3's base64 PEM body.certifi_distrusts_emsign_ecc_g3(offline): loadsrequests.certs.where()and fails if G3's SHA-256 fingerprint is present, or if the bundle has fewer than 100 roots.Verified on the host (no builds)
pip download --require-hashes --no-deps --only-binary :all: --platform manylinux_2_28_{x86_64,aarch64} --python-version 3.14 --abi cp314 -r requirements.lockfetches all 14 files for each arch, including the cp314 manylinux wheels forcharset-normalizerandmultidict, and every hash matches.Requires-Distacross the 14 locked wheels plus PyPI's httpie 3.2.4 wheel (requests with[socks], Linux / py3.14 markers) against the set plus pip. All requirements are satisfied, with 0 unsatisfied.minimal build/minimal-checkCI. Two things are not checked yet: whetherpip checkbehaves as expected inside the sandbox, and the exact shape of the output tree.Related
pip3 install .shape and was not changed here.Needs a human reviewer per repo policy.
🤖 Generated with Claude Code