Skip to content

fix(docker): drop CA roots behind the compromised eMudhra intermediates - #128

Open
David Larsen (dc-larsen) wants to merge 4 commits into
mainfrom
dc-larsen/emudhra-ca-trust
Open

David Larsen (dc-larsen) wants to merge 4 commits into
mainfrom
dc-larsen/emudhra-ca-trust

Conversation

@dc-larsen

@dc-larsen David Larsen (dc-larsen) commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Updates the standard and heavy images so their TLS clients stop trusting the eMudhra intermediate CAs whose keys were disclosed on 2026-10-20 (details). In 3.4.0, curl, Python requests, Node, Trivy (go1.26.3) and TruffleHog (go1.25.12) all accept them.

Changes

  • Dockerfile, Dockerfile.heavy: fail the build unless ca-certificates is 20250419+deb13u1 or newer. That release drops the two roots the compromised intermediates chain to. Trivy and TruffleHog read the system store, so this covers them on their current Go toolchains. Changing the RUN line also avoids reusing a cached apt layer with the old bundle.
  • Dockerfile, Dockerfile.heavy: fail the build below Node 22.23.4, which rejects the compromised intermediates itself (NodeSource's setup_22.x already serves it). An earlier revision set NODE_OPTIONS=--use-openssl-ca instead; that's gone, so a caller's own NODE_OPTIONS no longer matters.
  • Dockerfile.heavy: certifi>=2026.10.19 for the system interpreter, which runs the Python CLI outside the locked venv.
  • CHANGELOG.md: entry under [Unreleased].

The certifi bump in uv.lock (2026.10.19) landed separately in #129.

Not in this PR:

  • Container scanners will keep flagging the Go stdlib in trivy and trufflehog until they're rebuilt on Go 1.26.10+ or 1.27.3+. Trivy needs a trivy-dist rebuild, and TruffleHog's latest release (3.99.3) is still on go1.27.2.
  • action.yml pins 3.4.0, so action users get this in the next release (chore(release): 3.4.1 #130).

Testing

Built both images locally, with TRIVY_IMAGE pointed at the published 3.4.0 image (the Socket-built Trivy base needs registry access). Then ran each client against the disclosure site's test hosts, dv-g3b-emudhra.we-have-a-problem.com and dv-g3b-aaa-emudhra.we-have-a-problem.com:

Client 3.4.0 This branch (standard and heavy)
curl, git accepts rejects
Python requests (venv and system interpreter) accepts rejects
Node fetch accepts rejects
Trivy accepts rejects
Go clients on go1.25.12 / go1.26.3 accepts rejects (standard only)

api.socket.dev, api.github.com, ghcr.io, pypi.org, the npm registry and Trivy's real DB download still connect. smoke-test-docker.sh passes for the main and heavy check sets. scripts/integration-test-docker.sh (standard image) and uv lock --locked pass.

To check by hand:

docker run --rm --entrypoint curl <image> -sS -o /dev/null -w '%{http_code}\n' https://dv-g3b-emudhra.we-have-a-problem.com/

3.4.0 prints 200; this branch fails certificate verification.


Note

High Risk
Changes container-wide TLS trust and Node TLS behavior; misconfiguration could break legitimate HTTPS or leave a gap if version checks fail silently—but the intent is critical security hardening after a CA compromise.

Overview
Hardens TLS trust in the standard and heavy Docker images after the disclosed eMudhra intermediate CA compromise, so bundled clients stop accepting certificates chaining to the affected roots.

Both Dockerfile and Dockerfile.heavy now fail the image build unless installed ca-certificates is at least 20250419+deb13u1, which drops the roots those intermediates chain to. That patched system store covers curl, git, Trivy, TruffleHog, and Python in the locked venv. NODE_OPTIONS=--use-openssl-ca is set so Node and the Socket npm CLI use that system store instead of Node’s still-vulnerable bundled CAs until upstream ships a fix.

The heavy image additionally pins certifi>=2026.10.19 on the system interpreter used by the Python CLI. CHANGELOG.md documents the fix and notes scanners may still flag CVE-2026-111943 on the Go binaries until they’re rebuilt on newer Go versions.

Reviewed by Cursor Bugbot for commit 8e82296. Configure here.

@lelia

lelia commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Pushed fe2451d on top of this branch to close the three gaps listed under "Not in this PR":

  • Dockerfile.heavy: same ca-certificates >= 20250419+deb13u1 check.
  • Dockerfile.heavy: certifi>=2026.10.19 on the pip install socketsecurity line. The Python CLI runs on the system interpreter, not the locked venv, so the uv.lock bump doesn't reach it.
  • Both Dockerfiles: ENV NODE_OPTIONS=--use-openssl-ca, so Node and the Socket npm CLI use the patched system store until Node ships its fix.

CHANGELOG entry updated to match.

Rebuilt both images locally (TRIVY_IMAGE pointed at the published 3.4.0 image, as before) and ran each client against both test hosts:

Client standard heavy
curl, git rejected rejected
Python (venv and system interpreter) rejected rejected
Node fetch rejected rejected
Trivy rejected (x509: certificate signed by unknown authority) rejected

api.socket.dev, registry.npmjs.org, github.com and Trivy's real DB download still connect. socket --version and socketcli --version run. smoke-test-docker.sh --skip-build passes with --check-set main and --check-set heavy.

Release and the Python CLI 2.11.2 bump for heavy (SocketDev/socket-python-cli#415) are staged separately.

@lelia
lelia deployed to socket-firewall October 21, 2026 02:22 — with GitHub Actions Active
@lelia lelia mentioned this pull request Oct 21, 2026
3 of 10 tasks
The private keys for eight eMudhra intermediate CAs leaked (disclosed
2026-10-20). Every TLS client in the 3.4.0 image still trusts
certificates issued from them.

Require ca-certificates 20250419+deb13u1 or newer. It removes emSign ECC
Root CA - G3 and AAA Certificate Services, the two roots those
intermediates chain to. The bundled Trivy and TruffleHog read the system
store, so they reject the chains even on their current Go toolchains.

Bump certifi to 2026.10.19, which drops the same emSign root for the
requests calls to our API and GitHub.
Apply the ca-certificates floor to Dockerfile.heavy, floor certifi on the
heavy image's system interpreter (which runs the Python CLI outside the locked
venv), and set NODE_OPTIONS=--use-openssl-ca in both images so Node and the
Socket npm CLI use the patched system store until Node ships its fix.
@lelia
lelia force-pushed the dc-larsen/emudhra-ca-trust branch from fe2451d to 8e82296 Compare October 21, 2026 02:51
@lelia
lelia deployed to socket-firewall October 21, 2026 02:51 — with GitHub Actions Active
@lelia

lelia commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 8e82296. Configure here.

…tem store

Node 22.23.4 rejects the compromised eMudhra intermediates itself, and
NodeSource's setup_22.x already serves it. Fail the build on an older Node
and drop NODE_OPTIONS=--use-openssl-ca, which a caller's own NODE_OPTIONS
would have overridden.
@lelia
lelia deployed to socket-firewall October 21, 2026 20:38 — with GitHub Actions Active

This branch was successfully deployed

1 active deployment
socket-firewall — 311bc4e3 Deployed Oct 21, 2026 by lelia via analyze #132
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