Repository navigation
SECURITY: node, node-lts: backport CVE-2026-111943 eMudhra fixes (nodejs/node#66871, #66877) - #946
Merged
Conversation
Eight eMudhra/emSign intermediate CA keys are compromised (Mozilla bug 2083449). Upstream node merged two fixes to main on 2026-10-20; neither is in a release yet. Carry both as patches on node 26.10.0 and node-lts 24.19.0: - nodejs/node#66871: SPKI-SHA256 blocklist of the 8 compromised keys, checked in a cert-verify callback on every SSL_CTX; a hit reports CERT_REVOKED. Applies to node 26.10.0 minus the crypto_tls.cc hunks (an OpenSSL 4.1 shim our tree lacks); hand-backported to 24.19.0 (no DTLS, different include/QUIC context). - nodejs/node#66877 (root-store half): drop emSign ECC Root CA - G3, emSign Root CA - C1, emSign ECC Root CA - C3 from node_root_certs.h (NSS 3.131.1). Applies cleanly to both. Both are applied by name with fail-closed grep checks. Adds two offline standalone tests per package; both fail against stock node 26.9.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
jtnkminimal
approved these changes
Oct 20, 2026
This was referenced Oct 20, 2026
Merged
bryan-minimal
enabled auto-merge
October 20, 2026 22:57
github-merge-queue
Bot
removed this pull request from the merge queue due to no response for status checks
Oct 21, 2026
bryan-minimal
added a commit
that referenced
this pull request
Oct 21, 2026
Brings in #946 (CVE-2026-111943 eMudhra backports for node and node-lts). Both sides kept: the two carried patches, their fail-closed greps and the standalone tests from #946, then this branch's llhttp wasm rebuild. The patches apply before the wasm census, which they do not touch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 21, 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.
What
CVE-2026-111943: eight eMudhra/emSign intermediate CA keys (EC P-384) were generated with tiny private scalars and are compromised (Mozilla bug 2083449; Go's fix is golang/go#82345). Each key appears in two certificates: one issued by emSign Root TLS/CS CA - G3, one cross-signed by Sectigo "AAA Certificate Services".
Upstream node merged two fixes to
mainon 2026-10-20. Neither is in a release yet, so this PR carries both as patches onnode26.10.0 andnode-lts24.19.0:d9a3f3d1)SSL_CTX(SecureContext, QUIC, DTLS). A hit reportsCERT_REVOKED.crypto_tls.cchunks (see below)src/dtlson v24; the include list,crypto_context.hand QUICtlscontext.cccontext differ, so the same lines went in by hand at the matching spotsae223417),src/node_root_certs.hhalfCorrection to the brief this PR was written from: #66877 removes three emSign roots, not only ECC G3. All three are gone because NSS 3.131.1 dropped them. ECC G3 is the Mozilla-store anchor for the compromised intermediates.
The 8 hashes in the patch match Go's
distrustedSPKIHasheslist exactly (checked programmatically).Deviations from upstream (also in each patch header)
VerifyCertChain) fromcrypto_tls.ccinto the new callback. That shim doesn't exist in 26.10.0 or 24.19.0, and ouropensslis 3.6.5, so thecrypto_tls.cchunks are dropped and the#if OPENSSL_VERSION_PREREQ(4, 1)block is left out ofCertVerifyCallback. Nothing else changes.tools/certdata.txthunks are dropped. That file feeds node's root-cert generator, not the build.test/parallel/test-tls-spki-blocklist.jsis included verbatim. It is only documentation, because our build doesn't run node's test suite.Why both patches are needed
tlstrusts node's bundled store by default (we configure with--shared-opensslbut not--use-openssl-ca), so the separate ca-certificates fix doesn't reach it. Removing the roots doesn't close the hole on its own either. A chain through a compromised key still verifies against any store that has a path to it:--use-system-ca/--use-openssl-ca, a caller-suppliedca, or the Sectigo AAA cross-sign (Apple, Microsoft and OpenJDK still trust it). The blocklist covers all of those.How
cve-2026-111943-*.patchand listed asLocalbuild deps.build.shapplies them by name (patch -Np1, never a glob), so a patch that goes missing fails the build. Fail-closedgrepchecks follow: thekBlockedSPKIstable and its install inSecureContext::Initmust be present, andemSign ECC Root CA - G3must be absent fromnode_root_certs.h. This is the same convention as the existing LIEF patch.node-ltsgainspatchas a build dep, whichnodealready had.-rNrevision marker. Nothing in pkgs uses the new stdlibrevision/patches[]ledger (minimal#1277) yet, and pkgs CI runs an olderminimal.upstream_versionis unchanged.Tests (offline standalone, added to both packages)
emsign_roots_removed: computes the SHA-256 of everytls.rootCertificatesentry and requires that none of the 3 removed roots appears, with a guard of at least 100 roots so an empty store can't pass.spki_blocklist_rejects_emudhra_intermediate: a local TLS server presents a throwaway self-signedlocalhostleaf plus one extra cert. The leaf is untrusted, so the patched callback scans every peer-sent cert.EM OV TLS CA - G3Cintermediate attached (public cert only; no compromised private key is used or published),authorizationErrormust beCERT_REVOKED.Negative control: run against stock node 26.9.0, both tests fail. The first reports
still bundled: emSign ECC Root CA - G3, emSign Root CA - C1, emSign ECC Root CA - C3; the second reportscontrol=DEPTH_ZERO_SELF_SIGNED_CERT blocked=DEPTH_ZERO_SELF_SIGNED_CERT.Patched builds (remote
min session, pkgbuild loadout, arm64):min package build --rebuild --verbose node-lts: real ~30 min compile, both patches applied (patching file …in the log),build finished, exit 0.min package build --rebuild --verbose node: same result, with the LIEF patch plus both CVE patches, DTLS hunk included.min check --packages node-ltsandmin check --packages node: every check passes, includingstandalone tests…Passwith the build-dependent checks live, not Skip.min check.standalone tests…Failcame back listing both test names.pkgs CI's
minimal-checkstill Skips standalone tests for these packages, so the green check above is not what verifies them.Blast radius
MINIMAL_SCIENCE_MODE=1 mip dump --packages --arch amd64, diffed against main: 28 spec hashes change. That isnodeandnode-ltsplus 26 dependents, all of them vianode-lts(nothing inpackages/importsnodedirectly):agent-browser, bash-language-server, capy, cf, dev-language-servers, emacs-config-dev1, emscripten, eslint, json-server, lerna, mermaid-cli, next, odin, ols, pi, pnpm, prettier, pyright, raygui, raylib, serve, typescript, typescript-language-server, vlt, wrangler, yarn
Unverified
minimal build.🤖 Generated with Claude Code