Repository navigation
fix: apply the certificate SPKI blocklist to Node and add entries - #55126
Merged
Merged
Conversation
Chromium carries a compiled-in list of SubjectPublicKeyInfo hashes that must never appear in a verified chain. Electron's Node had no equivalent, so the same chain could fail in a renderer and succeed in tls/https/fetch from the main or a utility process. - Node: wrap X509_verify_cert on every SecureContext and report CERT_REVOKED when a chain contains a blocked SPKI. - Chromium: add entries that Chrome distributes via CRLSet, which Electron does not consume, to the compiled-in list; Node's list mirrors them. - Testing binding hooks let the new spec extend Node's list at runtime and exercise the hook against the fixture chain.
Contributor
|
@MarshallOfSound has manually backported this PR to "44-x-y", please check out #55127 |
dsanders11
approved these changes
Oct 20, 2026
This was referenced Oct 20, 2026
Contributor
|
@MarshallOfSound has manually backported this PR to "42-x-y", please check out #55128 |
Contributor
|
@MarshallOfSound has manually backported this PR to "45-x-y", please check out #55129 |
Contributor
|
@MarshallOfSound has manually backported this PR to "43-x-y", please check out #55130 |
jkleinsc
approved these changes
Oct 20, 2026
UlisesGascon
added a commit
to UlisesGascon/node
that referenced
this pull request
Oct 20, 2026
Node.js embeds the Mozilla root store but has no equivalent of the browsers' CRLSet/OneCRL and no default online revocation checking, so a certificate chain through a compromised intermediate still verifies as long as it reaches a trusted root. Removing the affected roots would over-block, since other legitimate intermediates chain to them. Add a small compiled-in blocklist of SubjectPublicKeyInfo SHA-256 hashes and check every verified chain against it from a single SSL_CTX_set_cert_verify_callback hook. A hit is reported as X509_V_ERR_CERT_REVOKED through the normal verification path, so it honours rejectUnauthorized and surfaces as authorizationError on both client and server sockets. The hook is installed for every SSL_CTX Node.js creates: SecureContext, QUIC and DTLS. The OpenSSL 4.1 CN name constraint handling previously registered from crypto_tls.cc moves into the same hook, since OpenSSL allows only one. The initial entries are the eight eMudhra/emSign intermediates whose private keys were reported compromised in October 2026. The same list is shipped by Chromium, Go (CVE-2026-111943) and Electron. Sessions resumed from before this change are not re-verified, as is standard for TLS resumption; the exposure ends with the session timeout. Test-only hooks on the crypto binding, reachable with --expose-internals, allow the test to block a fixture key and exercise the full handshake. Refs: electron/electron#55126 Refs: golang/go#82345 Assisted-by: Claude, Codex Signed-off-by: Ulises Gascon <ulisesgascongonzalez@gmail.com>
UlisesGascon
added a commit
to UlisesGascon/node
that referenced
this pull request
Oct 20, 2026
Node.js embeds the Mozilla root store but has no equivalent of the browsers' CRLSet/OneCRL and no default online revocation checking, so a certificate chain through a compromised intermediate still verifies as long as it reaches a trusted root. Removing the affected roots would over-block, since other legitimate intermediates chain to them. Add a small compiled-in blocklist of SubjectPublicKeyInfo SHA-256 hashes and check every verified chain against it from a single SSL_CTX_set_cert_verify_callback hook. A hit is reported as X509_V_ERR_CERT_REVOKED through the normal verification path, so it honours rejectUnauthorized and surfaces as authorizationError on both client and server sockets. The hook is installed for every SSL_CTX Node.js creates: SecureContext, QUIC and DTLS. The OpenSSL 4.1 CN name constraint handling previously registered from crypto_tls.cc moves into the same hook, since OpenSSL allows only one. The initial entries are the eight eMudhra/emSign intermediates whose private keys were reported compromised in October 2026. The same list is shipped by Go (CVE-2026-111943) and Electron. Sessions resumed from before this change are not re-verified, as is standard for TLS resumption; the exposure ends with the session timeout. Test-only hooks on the crypto binding, reachable with --expose-internals, allow the test to block a fixture key and exercise the full handshake. Refs: electron/electron#55126 Refs: golang/go#82345 Assisted-by: Claude, Codex Signed-off-by: Ulises Gascon <ulisesgascongonzalez@gmail.com>
UlisesGascon
added a commit
to UlisesGascon/node
that referenced
this pull request
Oct 20, 2026
Node.js embeds the Mozilla root store but has no equivalent of the browsers' CRLSet/OneCRL and no default online revocation checking, so a certificate chain through a compromised intermediate still verifies as long as it reaches a trusted root. Removing the affected roots would over-block, since other legitimate intermediates chain to them. Add a small compiled-in blocklist of SubjectPublicKeyInfo SHA-256 hashes and check every verified chain against it from a single SSL_CTX_set_cert_verify_callback hook. A hit is reported as X509_V_ERR_CERT_REVOKED through the normal verification path, so it honours rejectUnauthorized and surfaces as authorizationError on both client and server sockets. The hook is installed for every SSL_CTX Node.js creates: SecureContext, QUIC and DTLS. The OpenSSL 4.1 CN name constraint handling previously registered from crypto_tls.cc moves into the same hook, since OpenSSL allows only one. The initial entries are the eight eMudhra/emSign intermediates whose private keys were reported compromised in October 2026. The same list is shipped by Go (CVE-2026-111943) and Electron. Sessions resumed from before this change are not re-verified, as is standard for TLS resumption; the exposure ends with the session timeout. Test-only hooks on the crypto binding, reachable with --expose-internals, allow the test to block a fixture key and exercise the full handshake. Refs: electron/electron#55126 Refs: golang/go#82345 Assisted-by: Claude, Codex Signed-off-by: Ulises Gascon <ulisesgascongonzalez@gmail.com>
2 of 13 tasks
nodejs-github-bot
pushed a commit
to nodejs/node
that referenced
this pull request
Oct 20, 2026
Node.js embeds the Mozilla root store but has no equivalent of the browsers' CRLSet/OneCRL and no default online revocation checking, so a certificate chain through a compromised intermediate still verifies as long as it reaches a trusted root. Removing the affected roots would over-block, since other legitimate intermediates chain to them. Add a small compiled-in blocklist of SubjectPublicKeyInfo SHA-256 hashes and check every verified chain against it from a single SSL_CTX_set_cert_verify_callback hook. A hit is reported as X509_V_ERR_CERT_REVOKED through the normal verification path, so it honours rejectUnauthorized and surfaces as authorizationError on both client and server sockets. The hook is installed for every SSL_CTX Node.js creates: SecureContext, QUIC and DTLS. The OpenSSL 4.1 CN name constraint handling previously registered from crypto_tls.cc moves into the same hook, since OpenSSL allows only one. The initial entries are the eight eMudhra/emSign intermediates whose private keys were reported compromised in October 2026. The same list is shipped by Go (CVE-2026-111943) and Electron. Sessions resumed from before this change are not re-verified, as is standard for TLS resumption; the exposure ends with the session timeout. Test-only hooks on the crypto binding, reachable with --expose-internals, allow the test to block a fixture key and exercise the full handshake. Refs: electron/electron#55126 Refs: golang/go#82345 Assisted-by: Claude, Codex Signed-off-by: Ulises Gascon <ulisesgascongonzalez@gmail.com> PR-URL: #66871 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Bryan English <bryan@bryanenglish.com> Reviewed-By: Tim Perry <pimterry@gmail.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
4 of 13 tasks
This was referenced Oct 20, 2026
2 tasks done
5 tasks done
tec27
added a commit
to ShieldBattery/ShieldBattery
that referenced
this pull request
Oct 21, 2026
44.9.1 adds the eight weak eMudhra/emSign intermediate keys to an SPKI blocklist that covers both Chromium's verifier and the main process's Node TLS (electron/electron#55126); 44.9.3 adds a batch of Chromium/V8 security backports. Both are inside the release-age quarantine, so the exact version is excluded from it.
fogtape
pushed a commit
to fogtape/nodejs-mobile
that referenced
this pull request
Oct 21, 2026
Node.js embeds the Mozilla root store but has no equivalent of the browsers' CRLSet/OneCRL and no default online revocation checking, so a certificate chain through a compromised intermediate still verifies as long as it reaches a trusted root. Removing the affected roots would over-block, since other legitimate intermediates chain to them. Add a small compiled-in blocklist of SubjectPublicKeyInfo SHA-256 hashes and check every verified chain against it from a single SSL_CTX_set_cert_verify_callback hook. A hit is reported as X509_V_ERR_CERT_REVOKED through the normal verification path, so it honours rejectUnauthorized and surfaces as authorizationError on both client and server sockets. The hook is installed for every SSL_CTX Node.js creates: SecureContext, QUIC and DTLS. The OpenSSL 4.1 CN name constraint handling previously registered from crypto_tls.cc moves into the same hook, since OpenSSL allows only one. The initial entries are the eight eMudhra/emSign intermediates whose private keys were reported compromised in October 2026. The same list is shipped by Go (CVE-2026-111943) and Electron. Sessions resumed from before this change are not re-verified, as is standard for TLS resumption; the exposure ends with the session timeout. Test-only hooks on the crypto binding, reachable with --expose-internals, allow the test to block a fixture key and exercise the full handshake. Refs: electron/electron#55126 Refs: golang/go#82345 Assisted-by: Claude, Codex Signed-off-by: Ulises Gascon <ulisesgascongonzalez@gmail.com> PR-URL: nodejs/node#66871 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Bryan English <bryan@bryanenglish.com> Reviewed-By: Tim Perry <pimterry@gmail.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
5 of 7 tasks
5 tasks done
DeJeune
added a commit
to CherryHQ/cherry-studio
that referenced
this pull request
Oct 21, 2026
<!-- Template from https://github.com/kubevirt/kubevirt/blob/main/.github/PULL_REQUEST_TEMPLATE.md?--> <!-- Thanks for sending a pull request! Here are some tips for you: 1. Consider creating this PR as draft: https://github.com/CherryHQ/cherry-studio/blob/main/CONTRIBUTING.md --> ### What this PR does Before this PR: Electron 44.4.4 without the upstream eMudhra certificate-key blocklist fix; Linux SQLite prebuilds pinned to that version After this PR: Electron 44.9.3 with the upstream certificate security fix, synchronized lockfile, an exact-version release-age exception, and verified x64/ARM64 SQLite prebuilds <!-- (optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: --> Fixes: N/A ### Why we need it and why it was done in this way The following tradeoffs were made: stay on Electron 44; allow this exact security release through the package-age gate The following alternatives were considered: Electron 45 (unnecessary major upgrade); Electron-only bump (breaks strict Linux native-version validation) Links to places where the discussion took place: [upstream fix](electron/electron#55126), [Electron 44 backport](electron/electron#55127), [published native prebuilds](https://github.com/CherryHQ/cherry-studio-better-sqlite3/releases/tag/better-sqlite3-v12.11.1-electron-v44.9.3-r1) ### Agent Note / Spec <!-- Link the note and Spec PR, or write `N/A — <reason>` for a local/mechanical change. --> Agent Note: N/A — mechanical upstream security update preserving the existing native packaging contract Spec PR: N/A — no new feature, architecture, or process Acceptance criteria: Regression — patched Electron runtime and matching, verified Linux prebuilds ### Verification <!-- List only evidence actually run. Map Spec work to AC IDs; use Regression/N/A for direct fixes or process changes. --> - Regression — `pnpm test:scripts scripts/__tests__/linux-native.test.ts scripts/__tests__/before-pack.test.ts`: 25/25 passed - Regression — `pnpm typecheck:node` and `pnpm typecheck:web`: passed - Regression — `pnpm rebuild:electron`: passed; actual Electron 44.9.3 runtime, ABI 149, and native `better-sqlite3` query verified on macOS - Regression — production `ensureLinuxNativeArtifact()` download and verification for x64/ARM64: passed; SHA-256, ELF architecture, Electron metadata, and GLIBC limits verified - Regression — `shasum -a 256 -c SHA256SUMS` and `gh attestation verify` for both native addons, restricted to the release workflow, tag, and source commit: passed - Regression — [native prebuild Release workflow](https://github.com/CherryHQ/cherry-studio-better-sqlite3/actions/runs/39600707391): passed; signed commit and tag verified on GitHub - N/A — `pnpm change:scope --base origin/main`, `pnpm check --plan`, and `pnpm docs:affected --base origin/main`: inspected; app-upgrade and Linux-packaging documentation remains accurate - N/A — `pnpm exec oxfmt --check package.json pnpm-workspace.yaml scripts/linux-native/release.json` and `git diff --check`: passed ### Breaking changes <!-- optional --> None ### Special notes for your reviewer <!-- optional --> Full application packaging and E2E not run; Linux prebuild release already available, with addon hashes unchanged and versioned manifests updated ### Checklist This checklist is not enforcing, but it's a reminder of items that could be relevant to every PR. Approvers are expected to review this list. - [x] Branch: This PR targets `main` - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [ ] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note <!-- Write your release note: 1. Enter your extended release note in the below block. If the PR requires additional action from users switching to the new release, include the string "action required". 2. If no release note is required, just write "NONE". 3. Only include user-facing changes (new features, bug fixes visible to users, UI changes, behavior changes). For CI, maintenance, internal refactoring, build tooling, or other non-user-facing work, write "NONE". --> ```release-note Updated Electron to block compromised eMudhra certificate keys in HTTPS connections. ``` Signed-off-by: suyao <sy20010504@gmail.com>
6 tasks done
gnguralnick
pushed a commit
to imbue-ai/default-workspace-template
that referenced
this pull request
Oct 22, 2026
… policy The pinned Fortress (Chromium 151) still ships emSign ECC Root CA - G3, and Playwright's --disable-component-update keeps Chrome's CRLSet from reaching it. The Fortress env.d unit now writes a Chromium managed policy, /etc/chromium/policies/managed/distrust-compromised-emudhra-intermediates.json, whose CADistrustedCertificates lists the eight intermediates from Mozilla bug 2083449, as base64 DER. Chromium distrusts by public key, so the Sectigo cross-signs of the same keys are covered too. Verified from Chromium 151.0.7908.0 source and the pinned Fortress binary, not at runtime: Fortress is not Chrome-branded and its binary carries the /etc/chromium/policies path and the CADistrustedCertificates policy (M132+, dynamic refresh). The certificates' SPKI hashes match the blocklist electron/electron#55126 adds; the new test checks the shipped policy parses and names exactly those keys.
shaanmajid
added a commit
to shaan-forks/clients
that referenced
this pull request
Oct 22, 2026
Electron 43.8.1 adds the eMudhra intermediate SPKI blocklist entries and applies the blocklist to Node TLS (electron/electron#55126, backported in #55130). 43.8.3 is the latest 43.x patch and also carries upstream Chromium security backports (electron/electron#55147).
Xmader
pushed a commit
to Distributive-Network/node
that referenced
this pull request
Oct 23, 2026
Node.js embeds the Mozilla root store but has no equivalent of the browsers' CRLSet/OneCRL and no default online revocation checking, so a certificate chain through a compromised intermediate still verifies as long as it reaches a trusted root. Removing the affected roots would over-block, since other legitimate intermediates chain to them. Add a small compiled-in blocklist of SubjectPublicKeyInfo SHA-256 hashes and check every verified chain against it from a single SSL_CTX_set_cert_verify_callback hook. A hit is reported as X509_V_ERR_CERT_REVOKED through the normal verification path, so it honours rejectUnauthorized and surfaces as authorizationError on both client and server sockets. The hook is installed for every SSL_CTX Node.js creates: SecureContext, QUIC and DTLS. The OpenSSL 4.1 CN name constraint handling previously registered from crypto_tls.cc moves into the same hook, since OpenSSL allows only one. The initial entries are the eight eMudhra/emSign intermediates whose private keys were reported compromised in October 2026. The same list is shipped by Go (CVE-2026-111943) and Electron. Sessions resumed from before this change are not re-verified, as is standard for TLS resumption; the exposure ends with the session timeout. Test-only hooks on the crypto binding, reachable with --expose-internals, allow the test to block a fixture key and exercise the full handshake. Refs: electron/electron#55126 Refs: golang/go#82345 Assisted-by: Claude, Codex Signed-off-by: Ulises Gascon <ulisesgascongonzalez@gmail.com> PR-URL: nodejs#66871 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Bryan English <bryan@bryanenglish.com> Reviewed-By: Tim Perry <pimterry@gmail.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
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.
Description of Change
SecureContextso a chain containing a listed key reportsCERT_REVOKED, matching what the Chromium stack already does.Checklist
npm testpassesRelease Notes
Notes: none