8000 SECURITY: httpie: hash-lock the dependency closure with certifi 2026.10.19 (CVE-2026-111943) by bryan-minimal · Pull Request #952 · gominimal/pkgs · GitHub
[go: up one dir, main page]

Skip to content

SECURITY: httpie: hash-lock the dependency closure with certifi 2026.10.19 (CVE-2026-111943) - #952

Merged
bryan-minimal merged 1 commit into
mainfrom
security/httpie-lock-certifi-emudhra
Oct 21, 2026
Merged

bryan-minimal merged 1 commit into
mainfrom
security/httpie-lock-certifi-emudhra

Conversation

@bryan-minimal
Copy link
Copy Markdown
Member

httpie's build.sh ran pip3 install --root "$OUTPUT_DIR" . with no pins, so pip resolved the whole dependency tree from PyPI at build time. The certifi that requests verifies 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-256 86A1ECBA089C4A8D3BBE2734C612BA341D813E043CF9E8A862CD5C57A36BBE6B). Mozilla distrusted that root after eMudhra's intermediate key was compromised (CVE-2026-111943, Mozilla bug 2083449).

Change

  • New 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 with uv 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.19 is 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.
    • Everything else was resolved with --exclude-newer 2026-10-06, so no same-day upload enters the lock. certifi is the one deliberate exception. As a result setuptools is 84.0.0, not today's 84.2.1, and multidict is 7.0.0, not 7.1.0.
    • httpie (installed from the pinned source tarball) and pip are left out. httpie requires pip for httpie cli plugins, and the python runtime dep's pip satisfies it, so a second copy under --root would shadow it. The header of requirements.lock documents both exclusions and how to regenerate the lock.
  • build.sh:
    • runs 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.
    • runs pip check over the installed tree (PYTHONPATH=<site-packages>), so a dependency missing from the lock fails the build instead of failing at import time.
    • fails if certifi/cacert.pem contains G3. The needle is a line of G3's base64 PEM body.
  • New standalone test certifi_distrusts_emsign_ecc_g3 (offline): loads requests.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)

  • Fetch: pip download --require-hashes --no-deps --only-binary :all: --platform manylinux_2_28_{x86_64,aarch64} --python-version 3.14 --abi cp314 -r requirements.lock fetches all 14 files for each arch, including the cp314 manylinux wheels for charset-normalizer and multidict, and every hash matches.
  • Closure: I evaluated every Requires-Dist across 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.
  • Build: not built locally. This relies on this PR's minimal build / minimal-check CI. Two things are not checked yet: whether pip check behaves as expected inside the sandbox, and the exact shape of the output tree.

Related

  • The pip that ships with python vendors its own certifi with G3. That is fixed separately in the python PR (pip 26.2.2 in ensurepip). httpie does not install its own pip, so that PR covers httpie's plugin installer too.
  • No other package in the repo hash-locks a pip closure today, so this lock format is new. diffoscope has the same unpinned pip3 install . shape and was not changed here.

Needs a human reviewer per repo policy.

🤖 Generated with Claude Code

…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>
@bryan-minimal
bryan-minimal requested a review from a team as a code owner October 20, 2026 22:52
@coderabbitai
coderabbitai Bot commented Oct 20, 2026
Copy link
Copy Markdown
Contributor

Warning

Review limit reached

  • Run on-demand review

This review includes 2 billable files and costs up to $0.50.

  • Ask an admin to make reviews automatic

Open in CodeRabbit

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.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available. Your 35 included PR review attempts over the past 7 days set your current allowance at 4 reviews per hour.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: gominimal/pkgs/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: a7aa2bcc-71af-4809-99e1-08f5484d4e11
📥 Commits

Reviewing files that changed from the base of the PR and between 24009b6 and 24d5296.

⛔ Files ignored due to path filters: 1
  • packages/httpie/requirements.lock is excluded by !**/*.lock
📒 Files selected for processing: 2
  • packages/httpie/build.ncl
  • packages/httpie/build.sh
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@bryan-minimal
bryan-minimal added this pull request to the merge queue Oct 21, 2026
Merged via the queue into main with commit 9485c7b Oct 21, 2026
11 checks passed
@bryan-minimal
bryan-minimal deleted the security/httpie-lock-certifi-emudhra branch October 21, 2026 05:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0