Skip to content

fix(tls): distrust compromised eMudhra certificate authorities - #37046

Merged
bartlomieju merged 3 commits into
mainfrom
fix/emudhra-ca-distrust
Oct 20, 2026
Merged

bartlomieju merged 3 commits into
mainfrom
fix/emudhra-ca-distrust

Conversation

@bartlomieju

@bartlomieju bartlomieju commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

Updates the bundled Mozilla CA certificates and TLS verifier following the eMudhra intermediate CA key compromise.

  • Require rustls-webpki 0.103.16, which rejects certificate paths containing the eight compromised public keys, including cross-signed certificates.
  • Require webpki-roots and webpki-root-certs 1.0.10, removing emSign ECC Root CA - G3 from both bundled root representations.
  • Update the transitive webpki-roots 0.26 dependency to the 0.26.11 compatibility wrapper so reqwest and hyper-rustls also use the fixed 1.0.10 bundle.
  • Refresh the lockfile, including the AWS-LC and pkg-config updates required by the verifier.
  • Require AWS-LC 1.18.2 and migrate ML-DSA imports to its stable signature API, using to_pkcs8v1() to preserve the existing PKCS#8 export format and avoid deprecation errors in CI.

Related upstream fixes: rustls/webpki#546 and rustls/webpki-roots#133.

Validation:

  • deno run -A tools/format.js --check
  • cargo check --locked -p deno_tls -p deno_node --features deno_core/v8
  • cargo clippy --locked -p deno_crypto --features deno_core/v8 -- -D warnings (Rust 1.95.0)
  • rustfmt --check --edition 2024 ext/crypto/mldsa.rs
  • Full workspace checks run in CI.
  • git diff --check
  • cargo check --locked -p deno_graph

AI assistance: Codex helped investigate the dependencies, update the manifests and lockfile, and prepare this PR.

Bump deno_graph to 0.111.1, which includes the merged TLS dependency update from denoland/deno_graph#670.

Comment thread Cargo.lock
"wasm-streams",
"web-sys",
"webpki-roots",
"webpki-roots 0.26.11",

@CertainLach CertainLach Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Note that reqwest used by deno_graph is still using the outdated webpki_roots
We can assume that this is safe, as there is only one version of rustls in the graph, thus there won't be two different crypto providers with different certificate sets, and the primary one is initialized in deno's cli/lib, but update to rustls might cause trusted CA store used by reqwest (and thus deno_graph) to diverge

@CertainLach CertainLach Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It also means that the downloads performed by @deno/loader would still be affected
(Actually, not sure about that one, does reqwest perform certificate validation on its own if build with js backend on node, or does it delegate everything to fetch()?)

Reqwest can now be unpinned across the crate graph, as this fix from littledivy this pin was waiting for (seanmonstar/reqwest#2080) was merged in seanmonstar/reqwest#2185

@CertainLach CertainLach Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actually, I might have misread the dependency graph here, the one who is still pulling old webpki-roots is hyper-rustls, not reqwest
The fact is some of the dependencies still pull outdated roots

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks, it was only a test dep, but I did a release for good measure

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks, it was only a test dep, but I did a release for good measure

Old webpki-roots are still in your Cargo.lock, I'm just unsure why if not deno_graph, I can look into that tomorrow, but it is not completely fixed in this PR

@bartlomieju
bartlomieju enabled auto-merge (squash) October 20, 2026 20:26
@bartlomieju
bartlomieju merged commit 9766cc5 into main Oct 20, 2026
136 checks passed
@bartlomieju
bartlomieju deleted the fix/emudhra-ca-distrust branch October 20, 2026 21:36
bartlomieju added a commit that referenced this pull request Oct 21, 2026
taylorific added a commit to taylorific/swampworks that referenced this pull request Oct 21, 2026
… own Deno

Java runtimes' cacerts (JKS or PKCS#12, read without keytool), the
distribution's Java store, an image's JAVA_HOME and any keystores named
in the new keystores argument are matched by public key like PEM
bundles. A usage stays exposed until the runtime's blocked.certs refuses
every reachable copy of an intermediate for it.

Electron apps are found under the usual install roots and their Electron
version compared with 42.11.16, 43.8.1 and 44.9.1. The Deno swamp runs on
(and any deno on PATH) counts as exposed: the rustls-webpki and
webpki-roots fixes are on Deno's main branch (denoland/deno#37046) but in
no release yet, and DENO_TLS_CA_STORE=system doesn't help.

Run on a Windows 11 host and an eclipse-temurin:21-jre image.

@KingTW01 KingTW01 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.

H

stack72 added a commit to swamp-club/swamp that referenced this pull request Oct 21, 2026
…ompromised eMudhra CAs (swamp-club#3699) (#3262)

## Summary

Fixes swamp-club#3699. A swamp binary built on Deno 2.9.7 still trusts
the compromised eMudhra certificate authorities: the trust store is
compiled into both the `denort` runtime the CLI runs on and the copy of
Deno it embeds for extensions. That leaves swamp's HTTPS/WSS traffic (S3
datastores, GitHub, 1Password, swamp-club, `--server`, extension HTTP
calls) open to interception by anyone holding one of the recovered
intermediate keys.

Deno 2.9.8 (released 2026-10-21) ships denoland/deno#37046:

- `rustls-webpki` 0.103.16 rejects certificate paths that include any of
the eight compromised intermediate public keys, cross-signed copies
included.
- `webpki-roots` / `webpki-root-certs` 1.0.10 drop `emSign ECC Root CA -
G3` from the bundled Mozilla roots.

## Change

- `.tool-versions`: `deno 2.9.7` → `deno 2.9.8`
- `Dockerfile`: `FROM denoland/deno:2.9.7` → `FROM denoland/deno:2.9.8`

`release.yml` needs no edit. Its setup-deno step, and every other
workflow that installs Deno, reads `.tool-versions` through
`deno-version-file`. `scripts/download_deno.ts` already fails a CI
compile when the running Deno doesn't match the pin, so released
binaries take both `denort` and the embedded `deno` from 2.9.8.

## Test Plan

- [x] verify-build on host Deno 2.9.8 (lint, fmt, type check, full test
suite, vuln scan, compile, binary check), plus verify-reviews and
verify-skills. Attestation `57b3813a-e10f-45c3-92e9-867517a53d70`.
- [x] Deno 2.9.8 is listed in `dl.deno.land/versions.json`, has a GitHub
release and is on Docker Hub as `denoland/deno:2.9.8`, so setup-deno and
the Docker build resolve.
- [x] The `deno` and `denort` zips for all five release targets return
200 on both GitHub releases and `dl.deno.land`.
- [x] Release-style compile in a Linux container (`CI=true`, host Deno
2.9.8): every `deno`/`denort` download came from the 2.9.8 release, and
a compiled probe reported runtime `2.9.8`.
- [x] `integration/toolchain_pins_rules_test.ts` passes (the
`Dockerfile` and every setup-deno step match `.tool-versions`).
- Not reproduced end to end: `www.emsign.com` chains to `emSign Root CA
- G1`, which isn't on the distrust list, so it loads on both 2.9.7 and
2.9.8. The disclosure test hosts from the issue are redacted, so whether
the fix is in rests on the upstream dependency bumps.

To check a released binary, the embedded Deno it extracts reports itself
as 2.9.8: run `~/.swamp/deno/deno --version`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_015Ai7cWZ3kCLTa7R1esN1XX

Co-authored-by: Blake Irvin <blakeirvin@me.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
mya-ake added a commit to mya-ake/portfolio that referenced this pull request Oct 21, 2026
2.9.8 is the first release that stops trusting the leaked eMudhra
intermediate CA (rustls-webpki 0.103.16 / webpki-roots 1.0.10,
denoland/deno#37046). The Docker base image stays digest-pinned to the
multi-arch index for denoland/deno:2.9.8.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
jonathanfallon added a commit to covoiturage-gouv-fr/mono that referenced this pull request Oct 21, 2026
Deno 2.9.8 retire de son magasin racine les autorités de certification eMudhra compromises (denoland/deno#37046).
boojamya added a commit to wholeearthlabs/realreel-c2pa that referenced this pull request Oct 22, 2026
….2.4 (#100)

2.9.8 distrusts the eight eMudhra intermediate CAs whose private keys were recovered and published (denoland/deno#37046); ocsp-leaf calls Cloud KMS over TLS to sign responses. Bumps ocsp-leaf to 0.2.4 for the release tag; no behaviour change.
cderv added a commit to quarto-dev/quarto-cli that referenced this pull request Oct 23, 2026
Deno 2.9.8 is the first release whose certificate path verification
rejects the compromised eMudhra / emSign intermediates
(denoland/deno#37046: rustls-webpki rejects paths through the eight
compromised keys, cross-signed ones included, and webpki-roots drops
emSign ECC Root CA - G3). Deno 2.7.14 accepts certificates chaining to
them, and Quarto's launchers force DENO_TLS_CA_STORE=system,mozilla,
so no store setting protects `quarto publish`, `quarto add` or the
tool installers. 2.9.7 and earlier lack the fix, so 2.9.8 is the
minimum (#15152).

The runtime migration plans also target the 2.9 line for Deno's Node
compatibility work (node:http upgrade handling, Node 26 targets); those
fixes were not checked against 2.7.14.
cderv added a commit to quarto-dev/quarto-cli that referenced this pull request Oct 23, 2026
Deno 2.9.8 is the first release whose certificate path verification
rejects the compromised eMudhra / emSign intermediates
(denoland/deno#37046: rustls-webpki rejects paths through the eight
compromised keys, cross-signed ones included, and webpki-roots drops
emSign ECC Root CA - G3). Deno 2.7.14 accepts certificates chaining to
them, and Quarto's launchers force DENO_TLS_CA_STORE=system,mozilla,
so no store setting protects `quarto publish`, `quarto add` or the
tool installers. 2.9.7 and earlier lack the fix, so 2.9.8 is the
minimum (#15152).

The runtime migration plans also target the 2.9 line for Deno's Node
compatibility work (node:http upgrade handling, Node 26 targets); those
fixes were not checked against 2.7.14.
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.

3 participants