社員のWindows やMacで動く新しいChrome やEdgeについては、安心してよさそうです。ただ、スマホ のアプリに埋め込むAndroid WebViewは別の話でした。
Cloudflare が10月30日に公開した実測では、確認画面(チャレンジページ)に現れたAndroid WebViewの30〜40%が、eMudhraの弱い鍵につながる証明書をまだ受け入れています。弱い鍵で作られた偽の証明書が実際に見つかったことも、同じ報告に書かれていました。
製品ごとの修正版は、eMudhraの件をまとめた記事 の表で引けます。
偽の証明書はあったが、傍受の形跡はない
Cloudflareは、オリジンへの接続を担うプロキシ(Pingora)にログを足し、10月21日に行き渡らせました。それから1週間で記録した、弱い鍵の証明書を使う接続の試みは約2万2,000件です。3分の2は確認用サイトなどへの接続で、残りのほとんどは、弱い中間CAで自分の証明書を用意したとみられるオリジンでした。
引っかかるのは約160件です。
編集部で割ると全体の0.7%ほどですが、証明書のSANに、接続先と無関係な他社のドメインが入っていました。消費者向けのIoT機器に関係するドメインもあります。有効期間が2年を超えるものもあり、パブリック認証局なら出せない長さでした。
もっとも、Cloudflareはこれを傍受の試みとはみていません。サーバーが自分の既定の証明書として出しているように見え、名前が接続先と違うのでホスト名の検証にも通らないからです。いくつかの例では、多くの拠点からの接続に同じ証明書が返り、経路の途中ではなくサーバー自身が出していると判断しました。検証を有効にした接続は、すべて拒否されています。
Cloudflareが見つけた偽の証明書の1枚は、日付が10月20日18時19分(協定世界時)でした。Mozillaのバグ報告が公開されてから、1時間たっていません。
驚く数字ですが、少し割り引いて読みたいところです。証明書の日付は作った人が書き込む値で、作った時刻の証明にはなりません。Bugzillaには同じ日の13時6分に、Mozillaが「複数の人が自力で鍵を算出し、一部は公開している」と書き込みました。
重いのは速さより、鍵を持てる人を絞れないことでしょう。DigiNotarなど過去に侵害された認証局では、鍵に触れられる相手はある程度限られていました。今回は公開の証明書からだれでも算出できます。これがCloudflareの挙げる違いです。
見えている範囲にも限りがあります。Cloudflareが記録したのは自社からオリジンへの接続で、社員のPCとSaaSの間の通信は見ていません。同社は、間接的な兆候も今のところ見ていないとしながら、慎重に狙いを絞った傍受までは否定できないと書きました。
編集部は先の記事で、多くの会社で先に表に出るのは更新のあとの接続断だとみました。傍受の形跡が出ていない以上、その順番は変えていません。ただ、「鍵を算出できる」というだけの段階は過ぎました。更新の遅れた端末を、いずれ届くものとして放っておく理由はもうないでしょう。
Linuxを除く新しいブラウザーは0%近く、WebViewは横ばい
Cloudflareは、チャレンジページを使って訪問者の側を測りました。人間かどうかを確かめる、あの画面です。その一部から2つの測定用ホストへ接続を試み、弱い鍵の証明書を受け入れるかを記録しました。試行は直近1週間で5,000万回にのぼります。
Cloudflareのグラフ。上段はボットの兆候なし、下段はあり。赤がAndroid WebView 出典: Cloudflare「4 real? Tracking exploitation and patching of eMudhra's weak keys」 (引用)
Cloudflareのまとめは、新しいブラウザーはおおむね修正済みで、ボットと古いブラウザーは残っている、というものです。グラフの線を読むと、その差がよく分かります。
User-Agent
ボットの兆候なし
ボットの兆候あり
Chrome 156以降(Windows、macOS、Android)、Edge 156以降、Firefox 158以降、Safari 26以降
0〜5%ほど
線なし
Chrome 155以降(Linux)
60〜80%台
45〜60%ほど
Android WebView
20〜30%ほど
40〜50%台
Chrome 150未満(Windows)
80〜90%ほど
70〜90%ほど
全体
40〜60%ほど
60〜70%ほど
測定を変えた10月27日から30日までを、グラフから目で読んだ値です。1%単位の精度はありません。Linuxの新しいChromeだけは高いままで、Cloudflareは理由を書いていません。
Cloudflareの本文にあるWebViewの受け入れは、30〜40%です。グラフの線はボットの兆候で分かれていて、本文の幅はその間にあたります。どう合わせた数字かは示されていないので、ここでは本文の値を使います。
同じAndroidでも、Chromeの線は0%近くに張りついています。つまり、スマホのChromeで合格でも、そのスマホの社内アプリが合格したことにはなりません。
Googleによると、Androidには10月19日22時ごろ(協定世界時)に、Google Play開発者サービス経由で同等の更新を配りました。多くの端末に届いていて、再起動すればすぐ受け取れるそうです。ただ、これは端末の話で、WebViewに効くかまでは書かれていません。遮断の経緯はTECHNOVAの記事 にもあります。
WebViewが遅れる理由を、Cloudflareは書いていません。編集部は、Google Play開発者サービスが入っていない端末や、再起動されないまま動き続ける端末が、この30〜40%に混じっているとみています。WebViewのUser-Agentを借りたボットもいるはずです。
時間の動きも見逃せません。測定が止まっていた最初の週末をはさんで、修正が進んだ跡はありました。ネットワーク(ASN)別では、大きなネットワークで測定の半数超が受け入れたままです。自動で届くものは週末までにかなり届いたようです。ただ、そのあとの3日間はほとんど動いていません。待てば減るとは期待しないほうがよいでしょう。
30〜40%は自社の割合ではない
この数字を社内の報告にそのまま載せるのは、やめておいたほうが無難です。Cloudflare自身が、結果より先に断りを入れました。
Big caveat upfront: by design the traffic to these challenge pages is highly skewed. There are many (unconfirmed) bots in there. Also, only clients that execute JavaScript (like browsers) will send probes.
出典: Cloudflare「4 real? Tracking exploitation and patching of eMudhra's weak keys」
チャレンジページの通信はもともと偏っていて、未確認のボットが多く、測定の接続を送るのはJavaScriptを動かす相手だけ、という断りです。
情シスに効くのは後半でしょう。curl、pip、Goで作ったツール、Androidアプリの通信ライブラリは、JavaScriptを動かさないので1回も数えられていません。先の記事で「ブラウザ以外の仕組み」と呼んだものの多くは、この実測の外にいます。
グラフを読むときの注意は、ほかにもあります。
10月27日18時18分(協定世界時)から、無料プランのゾーンに出すチャレンジページの10%まで測定を広げました。社員が見る法人向けサイトとは、客層が違うかもしれません。
10月27日の跳ね上がりは、測定を変えたためです。G3のクロスサインを送り、CT(証明書の公開ログ)に載った印のSCTを外し、ca2のチェーンも替えました。更新が後退したわけではありません。
10月29日18時ごろに上段のChrome 150〜154(macOS)の線が落ちますが、修正が進んだのではありません。ボットの検知を増やして、通信が下段へ移った結果です。
SCTを外したあとの「受け入れ」は、弱い鍵を信頼し、CTも見ない状態を指します。確認用サイトが「だれにも気づかれずに攻撃を受けうる」とする相手です。
逆向きの偏りを持つ統計もあります。Cloudflareが案内する確認用サイトは、MozillaのDennis Jackson氏が公開したもので、弱い鍵のチェーンにつながってしまった接続の数を、User-Agentごとに載せました。
Cloudflareの測定
確認用サイトの統計
規模
5,000万回(1週間)
接続の成功26万8,264件(24時間)
見える相手
JavaScriptを動かすブラウザーとボット
確認用サイトにつなぎ、弱い鍵を受け入れたものだけ
目立つ相手
WebViewや古いChrome
curlが約56%、Zabbixが約16%、Python-urllibが約7%
見えない相手
curl、pip、Goのツールなど
確認用サイトにつながない大多数
統計は10月30日22時9分(協定世界時)までの24時間で、サーバー1台の50%の標本です。割合はUser-Agentごとの件数を編集部で足した値で、ブラウザーのものを全部足しても約9%でした。
curlが半分を超えるからといって、世の中のcurlの半分が未修正という話にはなりません。自分で確認しに来た人と、Zabbixのような監視からの定期的な接続が多く混じっているとみられます。User-Agentも自己申告です。
2つの統計から言えるのは、どの種類の相手が残りやすいかまで。Cloudflareは「ボットもセキュリティ更新が要るソフトウェアにすぎない」と書き、全体の代表なら状況はかなり厳しいとしました。だから、自社がその中のどこにいるかは、自社の端末で数えるしかありません。
うちの会社で残りやすい場所
社員がブラウザーだけでWebを使い、ブラウザーを最新に保てている会社に、この節の話は当たりません。Cloudflareを使っているかどうかも関係ありません。測っているのはサイトの側ではなく、訪問者の端末だからです。
修正の届き方と測定の有無で分けた、eMudhraの件で残りやすい場所 作成: 編集部 / 出典: Cloudflare、Google、Apple、GitHub、Playwright、we-have-a-problem.comの公開情報をもとに編集部が作成
社内アプリのWebView
Androidの業務アプリが画面をWebViewで出しているなら、最初に見る場所です。Googleによると、CTの強制が及ぶのは、最新のSDKを対象にしたアプリか、自ら有効にしたアプリです。古いSDKのまま更新していないアプリには、偽の証明書を見破る手がかりが一つ足りません。
WebViewの版も手がかりになります。自分で確認しに来た人の標本ですが、確認用サイトの統計では、Android WebView 156は220回中2回、121は219回中113回が受け入れでした。端末ごとに版を控えておくと、どこから試すかを決めやすくなります。
画面ではなくAPIの通信をOkHttpなどのライブラリで流すアプリは、Cloudflareの数字に入らない点にも注意が要ります。iPhoneはAppleのネットワーク機能を使うアプリなら自動で遮断されますが、独自の一覧を持つアプリは開発元への確認になります。
キオスクと受付端末
受付のタブレットやサイネージは、悪い条件がそろいがちです。再起動すればすぐ受け取れる更新も、電源を入れたまま何か月も動く端末では、後回しになっているかもしれません。Google Play開発者サービスのない端末は、この経路自体を使えないはずです。
確認用サイトが示す回避策は、Androidの設定の「信頼できる認証情報」からルートを無効にする方法です。機種によってはできず、AAA Certificate Servicesを止めると一部のサイトでエラーが出ることもあります。Electron製のアプリなら、修正済みのElectronで作り直した版を待つしかありません。Electronの勧告にも、アプリ側の回避策はないとあります。
買った部署が持っていて、情シスの台帳に載っていない端末も多いでしょう。
自動テストのブラウザーとスクリプト
Playwrightで動かすChromiumは、社員のChromeと同じようには守られないとみたほうがよいでしょう。Chromeが緊急の遮断に使うCRLSetは、chrome://componentsに出るコンポーネントです。ところがPlaywrightは既定で--disable-component-updateを付けて起動します(ソースのchromiumSwitches.tsで確認)。起動後にコンポーネントを更新しない指定です。
使うブラウザーの版もPlaywrightの版ごとに決まるので、ツールを上げるまで古いままです。確認用サイトの統計にも、User-AgentにHeadlessChromeを含む接続が、24時間で少なくとも575件ありました。同じ統計で、Chrome 155(Linux)は確認1,573回のうち1,459回が受け入れです。先の表でLinuxの線が高いのも、サーバーで動く自動化のブラウザーが混じっているためかもしれません。ほかの自動化ツールも、既定のフラグを見ておくとよいでしょう。
開発者のMacとmacOSのランナーにも、似た穴があります。Appleの案内では、Safariやメールは自動で遮断される一方、macOSのcurl、git、python3などは/etc/ssl/cert.pemを見るため、将来のmacOSの更新まで受け入れる場合があります。手で一覧から外しても、macOSの更新で戻ることがあるそうです。確認用サイトは、10月26日のmacOS 27.2で実際に元に戻ったと指摘しました。
スクリプトの側の修正は、証明書の信頼の一覧の地図 とPython 3.15.2などの記事 で、言語ごとに引けます。
PyPIに公開するActionsは1.14.3へ
GitHub ActionsからPyPIへパッケージを公開しているなら、pypa/gh-action-pypi-publishの版を見ます。GitHubの勧告は、1.14.2以前を対象、1.14.3を修正版としました。深刻度はCritical(9.3)で、CVEは付いていません。1
原因は同梱のルート証明書です。古い版はcertifi経由でemSignのルートを含み、このActionが頼るSigstoreも、Trusted PublishingとDigital Attestationsでcertifiの一覧を使います。
9.3という数字の受け取り方には、少し注意が要ります。同じ件のElectronの勧告はCVSS 3.1で7.4で、攻撃の複雑さをHighとし、通信を傍受できる立場を前提に挙げました。pypi-publishはCVSS 4.0で、複雑さはLowです。
版の違う点数は単純に比べられません。攻撃の筋書きも書かれていないので、数字だけで今日の最優先と決めなくてよいでしょう。編集部が気にしているのは、セルフホストのランナーです。傍受できる立場が前提だとすれば、社内のネットワークやプロキシを通る分、GitHubが用意するランナーより条件に近づくためです。
見落としやすいのは版の固定です。READMEの例は@release/v1というブランチを指す書き方ですが、同じREADMEがタグかSHAでの固定を勧めています。固定はよい習慣である半面、自動では変わりません。1.14.3のリリースは10月20日、勧告がGitHub Advisory Databaseに載ったのは10月30日でした。データベースをもとにした通知に頼っていると、気づくのは10日ほどあとだったかもしれません。
自前でtwineやSigstoreを使う構成は、certifiを2026.10.19以降、sigstoreを4.5.1以降にします。PyPIに公開していない会社には関係ありません。なお、勧告はすでに公開したパッケージの点検には触れていません。
週明けまでに確認すること
台帳からAndroid端末を抜き出し、WebViewを使う社内アプリ、キオスク、受付端末に印を付けます。端末ごとに、アプリ一覧の「Android System WebView」の版も控えます。Googleの案内どおり一度再起動して、端末に更新を受け取らせます。
印を付けた端末の代表で、確認用サイト の表を実行します。社内アプリは、WebViewで同じURLを開ける検証版で試します。合格の印は接続に失敗したことだけを示すので、行のリンクも開き、警告なしで開いたら影響ありと判断します。
サーバー(本番なら同じ構成の検証機)、CIのジョブ、開発者のMacから、次のコマンドを実行します。外に出られない環境は、同じサイトのchains.zipとOpenSSLで、一覧だけを試せます。
curl https://dv-g3b-emudhra.we-have-a-problem.com/
curl https://dv-g3b-aaa-emudhra.we-have-a-problem.com/
curl https://dv-g3b-noct-emudhra.we-have-a-problem.com/
curl https://dv-g3b-aaa-noct-emudhra.we-have-a-problem.com/
git ls-remote https://git-emudhra.we-have-a-problem.com/check.git
証明書のエラーが出れば遮断できています。中身が返ったり、gitがコミットを表示したりすれば未修正です。pipとGoで作ったツールはcurlでは判定できません。pipはpython -m pip --version(26.2.2以降)、Goはgo version <実行ファイル>(1.27.3か1.26.10以降)で見ます。
Playwrightなどの自動化ツールを上げ、CIのジョブの中で、手順3の4つのURLをそのブラウザーで開きます。結果をログに残しておけば、次の更新のあとも比べられます。
import { chromium } from 'playwright';
const browser = await chromium.launch();
for (const h of ['dv-g3b', 'dv-g3b-aaa', 'dv-g3b-noct', 'dv-g3b-aaa-noct']) {
const page = await browser.newPage();
const url = `https://${h}-emudhra.we-have-a-problem.com/`;
const r = await page.goto(url).then(() => 'CONNECTED', (e) => e.message.split('\n')[0]);
console.log(h, r);
await page.close();
}
await browser.close();
CONNECTEDと出れば未修正で、net::ERR_CERT_で始まるエラーなら遮断できています。タイムアウトなど、ほかのエラーでは判定できません。ignoreHTTPSErrors: trueを付けたジョブは証明書の検証を飛ばすので、必ずつながります。
grep -rn "gh-action-pypi-publish" .github/workflowsで公開のワークフローを探します。版かSHAで固定していれば1.14.3以降へ上げ、@release/v1なら実行ログの「Download action repository」の行で、取得したコミットがタグv1.14.3(7245906)かそれより新しいかを見ます。
合格は、試した経路にしか当てはまりません。Cloudflareは10月20日のブログで、ブラウザーの合格はバックグラウンドのサービスの安全を示さず、アプリが別の検証の仕組みを使うならcurlの合格も同じだと注意を促しました。TLSを復号するプロキシの内側では、結果はプロキシの一覧を映します。
確認用サイトを社内で使うときは、次の点に気をつけてください。
Apple向けのページにある、github.comを確認用サーバーへ向け替えるデモは、社内で使わないでください。fake-user@を外すと、GitHubの認証情報が相手のサーバーに送られます。
接続に成功した相手のUser-Agentは、統計として公開されます。社名や内部のシステム名を入れたUser-Agentで試さないでください。
証明書のエラーを消すために、検証を切らないでください。ca1とca2のcloudflarecaptcha.comはCloudflareの測定用で、確認には使いません。
Cloudflareは報告の終わりで、ルートストアを固定の一覧のままにせず、失効やCTの情報まで素早く更新できる仕組みが要ると書き、upkiという取り組みを挙げました。ただ、そうした仕組みが受付のタブレットにまで届くのは、だいぶ先でしょう。それまでは、「ブラウザーは自動で守られた」と言える範囲を、自社の台帳の上で線引きしておくしかありません。