2026年10月22日 時点の情報です

ブラウザは守られた。
ターミナルの中は、まだかもしれない。

インドの認証局 eMudhra の中間証明書8件で、署名用の秘密鍵が誰でも復元できる状態だったと分かりました。Chrome や Firefox はすでに遮断しています。Node.js、Bun、Python、Go のような開発ツールは、自分で更新するまで古い証明書リストを使い続けます。

漏えいした P-384 秘密鍵の1つ(48バイトを16進で表示) 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 本来は384ビットの乱数です。研究者のスコット・ヘルム氏によると、実際の鍵の1つは整数の4でした。8件とも256未満の値で、ノートPCで1秒もかからず全部を復元できたと報告されています。

まず結論

影響があるかどうかは、使っている場所で決まります

  • 対策済みChrome、Firefox、Safari、Edge でのWeb閲覧。各社が10月17日から20日にかけて該当証明書を遮断しました。
  • 影響なしLet's Encrypt や Google Trust Services の証明書で公開している自分のサイト。Vercel、Cloudflare、GitHub Pages の標準の証明書はこちらです。
  • 要確認開発マシン、サーバー、Docker、CI で動かしている Node.js、Bun、Python、Go、curl などが外部のHTTPSにつなぐ通信。

実際の悪用は、10月22日時点では報告されていません。それでも鍵の値はすでに公開されていて、誰でも同じ偽証明書を作れます。

何が起きたか

証明書の連鎖の、真ん中の鍵が漏れました

HTTPSでは、接続先が本物かどうかを証明書の連鎖で確かめます。OSやツールに入っているルート証明書が中間証明書に署名し、中間証明書がサイトの証明書に署名します。

eMudhra の説明では、2025年4月の鍵生成スクリプトの欠陥で弱い鍵ができ、名前が似ていたため本番に使ってしまったそうです。弱い鍵は約17か月のあいだ、公開されている証明書から復元できる状態でした。

なぜブラウザ以外が危ないのか

開発ツールは、失効も発行記録も確かめません

ブラウザは、証明書の失効リストを自動で受け取り、発行記録の公開ログ(Certificate Transparency)に載っていない証明書を拒否します。偽の証明書はログに載っていないので、ブラウザでは通りません。

Node.js、Bun、Python、Go、curl、パッケージマネージャーの多くは、本体やディスクにある証明書リストだけを信頼します。失効もログも標準では確かめません。リストからルートを消した版に更新するまで、偽の証明書でも検証が通ります。

狙われるのは通信の途中です。攻撃者が公衆Wi-Fi、乗っ取ったルーター、書き換えたDNSなどで通信の間に入ると、偽の api.anthropic.com や偽の npm レジストリになりすませます。リクエストに載せたAPIキーやトークンを読まれたり、ダウンロードするパッケージを差し替えられたりする恐れがあります。

対応状況

どこまで上げればよいか

修正版の番号は、各プロジェクトのリリースノートと配布物で確かめたものです。同じツールが Homebrew、nvm、mise などで複数入っていることがあるので、全部を確かめてください。

ツール修正版状態補足
Node.js22.23.4 / 24.22.1 / 26.12.1修正あり10月21日公開。ルート証明書を NSS 3.131.1 に更新し、漏れた鍵を含む連鎖を拒否します
Bunなし未修正最新の 1.4.3 は10月10日公開で、修正を含みません。1.3.11 の本体に同じルートが入っていることを確認しました
Python certifi2026.10.19修正ありrequests などが使う証明書リストです。仮想環境ごとに入っているので、プロジェクトごとに上げます
uv0.13.4修正あり本体に同梱した証明書リストを更新しました(GHSA-hq85-5cpj-mr62)
Go1.27.3 / 1.26.10修正あり標準ライブラリで該当の連鎖を拒否します。Goで作ったバイナリは再ビルドが必要です
curl の証明書リスト(Homebrew ca-certificates)2026-10-20修正ありこの版で emSign ECC Root CA - G3 が消えていることを確認しました
cloudflared最新版更新版ありCloudflare が更新版を出したと告知しています。10月22日時点の最新は 2026.10.3 です
Linux の ca-certificates各ディストリの更新版ディストリ次第Docker のベースイメージも含めて、パッケージを更新してからイメージを作り直します

Bun はまだ修正版がありません。外部APIにキーを送る処理を Bun で動かしているなら、修正が出るまで Node.js で動かすか、信頼できるネットワークでだけ動かすのが安全です。

Claude Code に頼む

そのまま貼れるプロンプト

調べる、承認してから直す、の順に分けています。最初から「全部直して」と頼むと、どこが古かったのかが記録に残りません。

1. このマシンを診断する

2026年10月に見つかった eMudhra(emSign)中間証明書の秘密鍵漏えいについて、このマシンが影響を受けるかを調べてください。まだ何も更新しないでください。

対象: Node.js、Bun、Deno、Python(certifi)、uv、pip、Go、curl、Homebrew の ca-certificates、cloudflared、OS の証明書ストア、ローカルにある Docker イメージ

1. 各ツールについて、インストール場所とバージョンを実際にコマンドを実行して調べてください。Homebrew、nvm、mise、asdf などで同じツールが複数入っていれば全部挙げてください
2. 修正版の番号は、各プロジェクトの公式リリースノートかセキュリティ告知で確かめてください。ニュース記事やまとめサイトの番号は使わないでください。確かめられなかったものは「未確認」と書いてください
3. できるものは、そのツールが信頼するルート証明書に「emSign ECC Root CA - G3」が入っているかを直接調べてください(例: Node.js なら tls.rootCertificates を X509Certificate で解析する)
4. 結果を「ツール / 場所 / 今のバージョン / 修正版 / 判定 / 確認方法」の表にしてください
この書き方にした理由
  • Node.js と Bun は証明書リストを本体に埋め込んでいます。OS を更新しても直らないので、ツールごとに見る必要があります
  • 同じツールが複数入っていると、ターミナルで使う版と本番スクリプトが使う版が違うことがあります
  • この件の修正版番号は、ニュースサイトどうしで食い違っていました。公式のリリースノートで確かめるよう指定しています
  • 「更新しないで」と書くことで、最初は調べるだけにとどめます。何が古かったかが表に残ります

2. 承認してから更新する

さっきの表で修正版より古かったものを、修正版に更新してください。

- 更新する前に、何をどのコマンドで更新するかを一覧にして、私の承認を待ってください
- 更新したら、もう一度バージョンとルート証明書の中身を調べて、更新前と並べて見せてください
- Bun のように修正版がまだないものは、更新せずに「未修正」として残してください
- 証明書エラーが出ても、NODE_TLS_REJECT_UNAUTHORIZED=0、verify=False、curl -k、InsecureSkipVerify などで検証を無効にしないでください。エラーが出たらそこで止めて報告してください
この書き方にした理由
  • Homebrew での更新は、ほかのツールの依存も一緒に上がることがあります。先に一覧を見て判断できるようにしています
  • 更新前と更新後を並べると、本当に直ったかを自分の目で確かめられます
  • 証明書エラーを消すために検証を切ると、今回の修正が無意味になります。Cloudflare も告知で、検証を無効にして回避しないよう呼びかけています

3. 全リポジトリの実行環境を洗い出す

ホームディレクトリ以下にある自分のリポジトリを全部見て、本番と CI で使っている実行環境のバージョン指定を洗い出してください。

見る場所: .nvmrc、.node-version、package.json の engines と packageManager、Dockerfile の FROM、GitHub Actions の setup-node / setup-go / setup-python / setup-bun、go.mod の go と toolchain、mise.toml、.tool-versions、requirements や uv.lock に入っている certifi のバージョン

修正版より古いものを、リポジトリごとに表にしてください。直すのは私が選んだリポジトリだけにして、リポジトリごとにブランチを切って PR にしてください。
この書き方にした理由
  • 手元のマシンを直しても、Docker イメージ、サーバー、CI は古いバージョンのまま動き続けます
  • Go で作ったバイナリは、Go を更新したあとに再ビルドしないと直りません
  • Python の certifi はプロジェクトごとのロックファイルに固定されています。マシン全体の更新では変わりません
  • 直す対象を自分で選ぶことで、動いているサービスがまとめて止まるのを避けます

4. 証明書の検証を切っている箇所を探す

私のリポジトリ全体から、TLS の証明書検証を無効にしている箇所を探してください。まだ書き換えないでください。

探すもの: NODE_TLS_REJECT_UNAUTHORIZED、rejectUnauthorized: false、verify=False、curl の -k と --insecure、InsecureSkipVerify: true、npm や yarn の strict-ssl false、git の http.sslVerify false

見つかった箇所ごとに、ファイルと行、なぜそうなっていそうか、どう直せばよいかを出してください。
この書き方にした理由
  • 検証を切っているコードは、ツールを修正版にしても偽の証明書を受け入れます
  • 開発中に一時的に入れた設定が、本番やCIに残っていることがよくあります

5. 自分のサイトの証明書を確かめる

次のドメインについて、openssl s_client で TLS 証明書を取得して、発行元(Issuer)と証明書の連鎖を一覧にしてください。eMudhra か emSign が含まれていたら教えてください。

ドメイン:
(ここに自分のドメインを1行に1つずつ書く)
この書き方にした理由
  • eMudhra は、問題のルートの配下にある約3万件の証明書を別のルートへ移すとしています。emSign の証明書を使っているサイトは、ブラウザがルートを外すと接続エラーになります
  • Let's Encrypt や Google Trust Services の証明書なら、この件で対応することはありません

やってはいけないこと

エラーが出ても、検証を切らない

  • 更新したあとに証明書エラーが出たら、相手のサイトが emSign の証明書を使っている可能性があります。検証を無効にせず、相手側の証明書の入れ替えを待ってください
  • emSign ECC Root CA - G3 を手で証明書リストに足し直さないでください。偽の証明書をもう一度受け入れることになります
  • 「Bun でも動いているから大丈夫」とは考えないでください。偽の証明書を受け入れていても、通信は普通に成功します

出典

確かめた情報