Repository navigation
fix(security): stop trusting the compromised eMudhra roots (v2.9.2) - #215
Closed
krish221997 wants to merge 1 commit into
Closed
krish221997 wants to merge 1 commit into
krish221997 wants to merge 1 commit into
Conversation
Eight eMudhra/emSign intermediate CAs were issued with 8-bit private keys, so anyone can sign a certificate for any domain with them. Node.js blocks them only from 22.23.4 / 24.22.1 / 26.12.1; on any older Node, an attacker on the network could present a forged certificate for api.withone.ai and read the user's API key. At startup, before any connection opens, the CLI now removes from Node's default CA list the root that signed those intermediates (emSign ECC Root CA - G3, matched by SPKI, as webpki-roots 1.0.10 and Mozilla NSS did) and the two cross-signing roots Ubuntu removed (matched by name, in case the system store is enabled). Global fetch honours the new list. - Needs tls.setDefaultCACertificates (Node 22.19+ / 24.5+). On an older Node without the fix, the CLI prints a one-line stderr warning asking the user to update Node. - Runs only in bin/cli.js, so importing @withone/cli as a library does not change the host process's TLS settings. - Never throws; about 10 ms at startup. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
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.
Why
Eight eMudhra intermediate certificate authorities were created with 8-bit private keys. Anyone can compute those keys and sign a valid-looking certificate for any domain, including
api.withone.ai. Browsers blocked them on Oct 17. Node.js only blocks them from 22.23.4, 24.22.1 and 26.12.1, released Oct 21. Users run the CLI on whatever Node they have, so most are still exposed.What
At startup, before any connection opens,
bin/cli.jscallsapplyCaGuard()(src/lib/ca-guard.ts). It removes these roots from the CA list every TLS client in the process uses, globalfetchincluded:The guard runs only in the binary. Importing
@withone/clias a library leaves the host process's TLS settings alone. It never throws and adds about 10 ms to startup.Verified
fetchfollows a changed default list when it's set before the first connection. With a root removed, a site that chains to it fails withUNABLE_TO_GET_ISSUER_CERT_LOCALLY, while other sites still work.emSign ECC Root CA - G3. The other emSign roots stay, and so do the roots behind our own domains: ISRG for Let's Encrypt and GTS for Google.ca-guard.test.tspass and typecheck is clean.resolveConfigtests, and they fail the same way on untouchedmain. They pick up this machine's config, and this PR doesn't touch them.After merge
Publish 2.9.2 to npm. Optionally deprecate older versions with a message pointing to 2.9.2:
🤖 Generated with Claude Code