macOSでのeMudhra対応:curl、Node、Python、Go、Java、Rust、Dockerで更新すべきもの
macOSはeMudhraの中間CAを遮断済みですが、curl、Node、pip、Java、コンテナ(Docker)は独自のルート証明書を使います。更新対象と確認方法を解説。
この記事は教育目的であり、正式なスマートコントラクト監査、法的助言、金融助言、またはプロトコル固有のセキュリティレビューに代わるものではありません。
eMudhraの8つの中間CA(TLS用が6つ、コード署名用が2つ)は、証明書そのものから誰でも復元できる秘密鍵で生成されていました。TLS用の6つを使えば、任意のドメインに対して有効な証明書に署名できます。ChromeとFirefoxは2026年10月17日から、Microsoftは20日から、そしてDennis Jacksonのページによると、Appleは22日からこれらをブロックしています。多くの開発ツールはこうしたブロックを参照せず、独自のルート証明書のリストで判断します。
Macでは、Appleのブロックはシステムのベリファイアを使うもの、たとえばSafari、Go、rustls-platform-verifierに適用されます。システムのcurlとpython3、Node、pip、Java、DockerのLinuxコンテナには適用されません。これらは独自のルート証明書を持っているからです。各ツールを修正済みのバージョンに更新し、ルート証明書を内蔵しているものは再ビルドし、公開サーバーに対してテストしてください。正しい結果は証明書エラーです。200が返る場合、そのツールはまだ中間CAを信頼しています。

何が起きたのか、なぜブラウザだけでは足りないのか
2026年10月17日、ある研究者がApple、Google、Microsoft、Mozillaのルートプログラムに対し、eMudhraの8つの中間CAの鍵が脆弱であると報告しました。Googleは、侵害された中間CAに署名したルート証明書としてemSign ECC Root CA - G3を挙げています。さらにSectigoのルート証明書AAA Certificate Servicesによるクロス署名を経由する別の経路もあります。このルート証明書は、古いルート証明書のリストにまだ含まれています。
Chromeは同日19:45 UTC(マドリード時間21:45)に、CRLSetの更新でこれらの中間CAの公開鍵をブロックしました。Mozillaは22:59 UTC(マドリード時間18日00:59)にOneCRLでブロックを完了し、Firefox 158.0.1をリリースし、NSSのバージョン3.131.1でルート証明書を削除しました。Googleは太平洋時間10月27日(火)の午前に、自社のルートストアからこのルート証明書を削除する予定です。
eMudhraによると、8つの中間CAのうち本番で使われていたのは1つだけで、エンドエンティティ証明書を発行したものはありません。GoogleとMozillaのDennis Jacksonはともに、Certificate Transparency(CT)のログにこれらの中間CAの証明書は存在しないとしており、CTを必須とするブラウザが攻撃を受けることはありえませんでした。リスクがあるのは、CTを必須とせず失効情報も確認しないプログラムです。つまりcurl、各言語のランタイム、pip、コンテナイメージです。これらのプログラムが中間CAを信頼しないようにするには、ルート証明書のリストかコードを更新する必要があります。
侵害された中間CAだけでは攻撃は成立しません。攻撃者は、ツールとサーバーの間にあるネットワーク、DNS、またはプロキシも制御する必要があります。具体的な攻撃ベクトルとその防ぎ方は、別の記事で扱います。
テスト結果の読み方
MozillaのDennis Jacksonは、影響を受けた中間CAの1つであるEM DV TLS CA - G3Bが署名したチェーンを持つテストサーバーを運営しています。ツールが接続に成功した場合、そのツールはまだこの中間CAを信頼しています。証明書エラーを返した場合は、信頼していません。
正確なメッセージはツールとバージョンによって異なります。「unable to get local issuer certificate」「certificate revoked」「no valid chains built」「CertDistrusted」「PKIX path building failed」はいずれも同じ意味です。テストが応答しない場合やDNSの解決に失敗した場合、その結果からは何もわかりません。もう一度実行してください。
同じページには、サーバーのバリエーションも記載されています。「-aaa-」を含むものはSectigoのクロス署名を経由し、「-noct-」を含むものはCTに一度も記録されていない証明書を使います。CTなしのバリエーションを受け入れるツールは、中間CAを信頼しているうえに、CTも必須としていません。
Cloudflareは重要な注意点を挙げています。テストは、テストした検証経路にしか当てはまりません。ブラウザやcurlがチェーンを拒否しても、別のTLSライブラリを使うアプリケーションについては何もわかりません。
curl
macOSのcurlは、システムのgit、python3、perl、ruby、opensslと同じく、失効情報を確認せずに/etc/ssl/cert.pemに対して検証を行います。そして、このファイルは更新されていません。Jacksonのページでは、影響を受ける2つのルート証明書をこのファイルから取り除く、sudoを使う手順が公開されています。システムファイルを変更するため、適用する前に全体を読んで判断してください。
Homebrewのcurlは、HomebrewのOpenSSLを使います。このOpenSSLはca-certificatesフォーミュラからルート証明書を取得します。修正済みのバージョンは2026-09-25_1以降です。これらを更新し、そのcurlを指定してテストしてください。
brew update
brew upgrade ca-certificates curl
brew list --versions ca-certificates curl
"$(brew --prefix curl)/bin/curl" -v -o /dev/null https://dv-g3b-emudhra.we-have-a-problem.com/
echo "exit: $?"期待される結果は「SSL certificate problem: unable to get local issuer certificate」と終了コード60です。終了コード0で「HTTP/1.1 200 OK」が表示される場合、そのcurlはまだチェーンを信頼しています。curlはCTを必須としないため、まさにJacksonのページが説明している種類のクライアントです。
Node.js
Nodeはバイナリの中にMozillaのルート証明書のコピーを独自に持っているため、macOS側の対応の影響を受けません。修正済みのバージョンは26.12.1、24.22.1、22.23.4です。これらはルート証明書をNSS 3.131.1に更新し、ブロックされた公開鍵を拒否する処理を追加しています。nvm、fnm、Voltaを使っている場合は、現在使っているバージョンだけでなく、インストール済みのすべてのバージョンを更新してください。
node --version
node <<'NODE'
const https = require('node:https');
const req = https.get({
hostname: 'dv-g3b-emudhra.we-have-a-problem.com',
timeout: 10000,
rejectUnauthorized: true
}, res => {
console.log('WARNING: TLS ACCEPTED:', res.statusCode);
res.resume();
});
req.on('error', err => {
console.log('REQUEST REJECTED:', err.code, err.message);
});
req.on('timeout', () => {
console.log('INCONCLUSIVE: timeout');
req.destroy();
});
NODENode 24.22.1では、出力は「REQUEST REJECTED: CERT_REVOKED certificate revoked」です。20.19.2のような修正前の古いバージョンでは「WARNING: TLS ACCEPTED: 200」と表示されます。NODE_EXTRA_CA_CERTS、NODE_TLS_REJECT_UNAUTHORIZED=0、コード中のrejectUnauthorized: falseも確認してください。これらはNodeが受け入れる内容を変えてしまいます。
Python、pip、uv
Pythonでは、更新すべきルート証明書のリストが2つあります。インタープリターのリストは、インストール方法によって異なります。pipのリストはpipの中にあります。このインシデントに関するPythonの公式スレッドによると、pipはシステムのルートストアに加えて、常に自身が持つcertifiのコピーを読み込みます。REQUESTS_CA_BUNDLEや--certのようなオプションは、ルート証明書を追加するだけです。信頼できる修正方法はpipの更新です。
Python Software Foundationが公開した最低バージョンは、certifi 2026.10.19、pip 26.2.2、uv 0.13.4です。Python 3.15.1、3.14.9、3.13.17にはすでにpip 26.2.2が含まれています。古いpipでは更新そのものが古いルート証明書で行われるため、PSFはコマンドの中でパッケージのハッシュを固定することを推奨しています。各仮想環境の中で次を実行してください。
python3 -m pip --version
python3 -m pip install "pip @ https://files.pythonhosted.org/packages/3f/06/3e4420302363fbb71be3c7f35ce042f54bfca330e3e66b3a2e3c4cca579f/pip-26.2.2-py3-none-any.whl#sha256=fd7f4dfa8190e014013b9f08f3e973f4e4c26ffd179a204895533a7254813a70"
python3 -m pip install --upgrade "certifi>=2026.10.19"
python3 -m pip debug --verbose | grep certifi最後の行には、pipが持つコピーであるcertifi==2026.10.19が表示されるはずです。uvを専用のインストーラーで入れた場合、PSFが示すコマンドは「UV_SYSTEM_CERTS=true uv self update」です。Homebrewで入れた場合は「brew upgrade uv」です。
ある環境の2つのリストを確認するには、その環境のpython3で次のテストを実行してください。
import ssl
import socket
import certifi
host = "dv-g3b-emudhra.we-have-a-problem.com"
contexts = {
"default": ssl.create_default_context(),
"certifi": ssl.create_default_context(cafile=certifi.where()),
}
for name, ctx in contexts.items():
try:
with socket.create_connection((host, 443), timeout=10) as sock:
with ctx.wrap_socket(sock, server_hostname=host):
print(name, "WARNING: TLS ACCEPTED")
except ssl.SSLCertVerificationError as exc:
print(name, "TLS REJECTED:", exc.verify_message)
except Exception as exc:
print(name, "INCONCLUSIVE:", repr(exc))certifi 2026.10.19では、certifiの行に「TLS REJECTED: unable to get local issuer certificate」と表示されるはずです。defaultの行は、そのインタープリターが使うルートストアによって変わります。ACCEPTEDと表示された場合は、システムのルートストアかインストーラーのルートストアを更新してください。
Go
macOSでは、Goは検証をシステムのAPIに任せるため、Mac上のGoプログラムはAppleのブロックを引き継ぎます。問題は、Mac上でLinux向けにビルドするバイナリ、たとえばコンテナ用のバイナリです。そこではGoは独自のベリファイアを使います。Go 1.27.3と1.26.10は、crypto/x509にブロック対象の公開鍵のリストを追加しています(CVE-2026-111943)。「brew upgrade go」または公式インストーラーでGoを更新し、各バイナリを再ビルドしてデプロイし直してください。
テストするには、Linux上、またはそのバイナリが動くコンテナの中で次を実行してください。
go version
mkdir -p /tmp/emudhra-go && cd /tmp/emudhra-go
cat > main.go <<'EOF'
package main
import (
"fmt"
"net/http"
"time"
)
func main() {
client := &http.Client{Timeout: 10 * time.Second}
resp, err := client.Get("https://dv-g3b-emudhra.we-have-a-problem.com/")
if err != nil {
fmt.Println("TLS REJECTED:", err)
return
}
resp.Body.Close()
fmt.Println("WARNING: TLS ACCEPTED:", resp.Status)
}
EOF
go run main.goLinux上のGo 1.27.3では、出力は「x509: no valid chains built」で終わります。ルートストアが更新されていない環境の1.27.2では「200 OK」で終わります。ビルド済みのバイナリには、ビルドに使ったバージョンが含まれています。「go version」のあとにバイナリのパスを指定すると確認できます。
Java
10月21日より前に公開されたJDKは、デフォルトではこれらの中間CAをブロックしません。すでにインストールされているJDKも、それより古ければ同じです。修正済みのバージョン(OracleまたはOpenJDK 27.0.1.0.2 / 25.0.5.0.2 / 21.0.13.0.2 / 17.0.21.0.2 / 11.0.33.0.2、Oracle JDK 8u511 b32、Corretto 25.0.5.0.9 / 21.0.13.0.10 / 8.512.08.1、または同じバージョンのHomebrew openjdk / @21 / @17)に更新してください。更新できない場合は、修正済みのJDKからlib/security/blocked.certs(JDK 8ではjre/lib/security/blacklisted.certs)をコピーし、16個のSHA-256フィンガープリントが含まれていることを確認してから、Javaアプリケーションを再起動してください。Oracleはops.java/emudhraでもこのファイルを公開していますが、10月23日にはこのページにアクセスできませんでした。
Javaは、各JDKの中にある独自のルートストアcacertsを使い、macOSのブロックは参照しません。そのcacertsにemSign ECC Root CA - G3またはAAA Certificate Servicesが含まれていれば、JDKは、ブロック対象の証明書リストに入っていない限り、これらの中間CAを受け入れます。10月21日のOpenJDKのアドバイザリ(CVE-2026-91403)では、影響を受けるバージョンとして27.0.1、25.0.5、21.0.13、17.0.21、11.0.32.1、8u504、およびそれ以前が挙げられています。
この修正は、OpenJDKではJDK-8395142、OracleのリリースノートではJDK-8395555という番号です。ルート証明書は削除せず、eMudhraの中間CA 8個と、Sectigoがクロス署名した証明書8個をブロックリストに追加します。修正はすでに、Oracle JDK 27.0.1.0.2、25.0.5.0.2、21.0.13.0.2、17.0.21.0.2、11.0.33.0.2、8u511 b32、Corretto 25.0.5.0.9、21.0.13.0.10、8.512.08.1、そしてHomebrewのopenjdk、openjdk@21、openjdk@17のフォーミュラで公開されています。10月23日時点で、Homebrewのopenjdk@11とopenjdk@8、Zulu、Temurin 8と11にはまだ含まれていません。Temurin 21と25にも含まれていませんが、G3もAAAも同梱していないため、この証明書チェーンを拒否します。
Oracle JDK 8では、10月20日に公開された8u511(1.8.0_511-b09)は引き続き影響を受けます。修正済みは8u511 b32(1.8.0_511-b32、10月21日公開)です。「java -version」で確認し、「b32」と表示されなければ更新してください。OpenJDK 8(Temurin、Zuluなど)では、8u504以前が影響を受けます。10月23日時点でTemurinは修正版を公開していませんが、Corretto 8.512.08.1には修正が含まれています。
基本の対処は更新です。HomebrewのJDKの場合:
/usr/libexec/java_home -V
brew list --versions | grep openjdk
brew upgrade openjdk
brew upgrade openjdk@21
brew upgrade openjdk@17
for f in openjdk openjdk@21 openjdk@17; do
J="$(brew --prefix "$f")/bin/java"
[ -x "$J" ] && echo "$f:" && "$J" -version
done更新するのはインストール済みのフォーミュラだけにしてください。1行目はすべてのJDKを一覧表示するわけではなく、/Library/Java/JavaVirtualMachinesまたは~/Library/Java/JavaVirtualMachinesにリンクがあるものだけを表示します。openjdk@21やopenjdk@17のようなHomebrewのkeg-onlyフォーミュラは「brew list --versions」または「brew --prefix openjdk@21」でしか表示されないため、1つずつ確認する必要があります。名前だけでは判断できません。各JDKの実際のバージョンを上の一覧と照合してください。「brew list --versions」にはopenjdk 27.0.1.0.2、openjdk@21 21.0.13.0.2またはopenjdk@17 17.0.21.0.2と表示されるはずです。openjdk 27やopenjdk@21 21.0.13は影響を受けたままです。最後のループは各フォーミュラの「java -version」を表示します。IDEやSDKMAN!のJDKは、それぞれのインストーラーで更新します。
次のスニペットは、16個のSHA-256フィンガープリントを/tmp/emudhra16.txtに保存し、Mac上の各JDKのブロックリストにそのうちいくつが含まれているかを数えます。JDK 11以降ではファイル名はblocked.certs、JDK 8ではjreフォルダー内のblacklisted.certsです。
cat > /tmp/emudhra16.txt <<'EOF'
0164D7CEAE5BB909C272AF151FF44B1177AE9B47D9424B94F1D9558C30934D19
42C4ACCD12C4F59597925E1A08A7A90102608543809308D50EC427E118BA1493
432EC25F0D28DE9006D97BF752F17BBB2CD41F669933FCB072D9A1148D0261F3
45A883F349AEDFD5F3A649B5498FFB121712BA8B448F3F2A91DBC5A766FCDDBE
4B2460A466F95FD40113BCDCCA2CEB29B3B093921DE45474DA7DF48874C630B1
579480AEA166290BD3C643589E795FC0D0E54E86505D180F1DFF99EFD3199512
5F1DED4DD590AF74631290CF073B122A2AAC6A1FA479778A0BD43579BD832699
62B7F9868263F72F6911FC78CEAF72C1979158B7368BF648683BB2AA39B02E72
7485B51C0ED192878FA1D2F948FB529AE1842CC5086C4B67F7BE5B2039DE9489
84112972B8E59D14560AE7E7119654474AAD119990CF3722BFC1E3B91615E1FD
98B896625C0C230ADEEC3EB2CF6AAD5001ECF9156A68644E82374CE5833BC25B
9E39DE2881273ACC225A149C72BA3E0F51424963669AB633EE1DC7DF5DB067B4
A496E23AC0CAB8155FC9B117B97EAE368EFCBB9041AEC8804D5A308D2D01C2D8
CB6E15165AC802E9B3F993F16C25D41F4E81C21EBDE71AE1B012AC00BF9C7C3F
E7568FE6E12331F4FD7DE61DA4C7559D0F8EB192A218D4741A3BA75184333838
FD9D5C2DBBD4995AB69B8D50C439D9527B00529199C2FD01B2174EB58F07021F
EOF
for JDK in /Library/Java/JavaVirtualMachines/*/Contents/Home \
"$HOME"/Library/Java/JavaVirtualMachines/*/Contents/Home \
/opt/homebrew/opt/openjdk*/libexec/openjdk.jdk/Contents/Home \
/usr/local/opt/openjdk*/libexec/openjdk.jdk/Contents/Home; do
[ -x "$JDK/bin/java" ] || continue
F="$JDK/lib/security/blocked.certs"
[ -f "$F" ] || F="$JDK/jre/lib/security/blacklisted.certs"
N="$(grep -c -x -F -f /tmp/emudhra16.txt "$F" 2>/dev/null)"
echo "$JDK: ${N:-0}/16 eMudhra fingerprints in $(basename "$F")"
done修正済みのJDKは16/16と表示されます。16未満なら、まだ保護されていません。
特定のJDKをテストするには、そのJDKのjavaとjshellをPATHに置いて次を実行してください。
java -version
cat > /tmp/emudhra-java.jsh <<'EOF'
import java.net.*;
import javax.net.ssl.*;
var url = URI.create("https://dv-g3b-emudhra.we-have-a-problem.com/").toURL();
try {
var c = (HttpsURLConnection) url.openConnection();
c.setConnectTimeout(10000);
c.setReadTimeout(10000);
System.out.println("WARNING: TLS ACCEPTED: " + c.getResponseCode());
} catch (SSLHandshakeException e) {
System.out.println("TLS REJECTED: " + e.getMessage());
} catch (Exception e) {
System.out.println("INCONCLUSIVE: " + e);
}
/exit
EOF
jshell /tmp/emudhra-java.jshブロックリストを適用すると、出力は「TLS REJECTED: (certificate_unknown) PKIX path validation failed」となり、その後に「Untrusted certificate: CN=EM DV TLS CA - G3B」が続きます。Temurin 21と25では、ルート証明書がないため「PKIX path building failed」と表示されます。文言はJavaのディストリビューションによって異なります。重要なのは「TLS ACCEPTED」が表示されないことです。
openjdk@11やopenjdk@8のようにJDKを更新できない場合は、フィンガープリントをそのJDKのブロックリストに追加する必要があります。同じバージョンの修正済みJDKにあるblocked.certsや、/tmp/emudhra16.txtの16個のフィンガープリントを使えます。これらはOpenJDKのJDK-8395142のPEMにあるものと一致します。Oracleはops.java/emudhraでもこのファイルを公開していますが、10月23日にはこのページにアクセスできませんでした。ファイルはAlgorithm=SHA-256という行で始まり、その後に1行に1つずつ16進数のフィンガープリントが続きます。次のスニペットは、元のファイルを検証し、16個のフィンガープリントがそろっていることを確認し、各JDKの既存のエントリーを残し、上書きされない.pre-emudhraのコピーを保存して、上の確認と同じJDKを順に処理します。
SRC=/tmp/emudhra16.txt
(
[ -s "$SRC" ] || { echo "ERROR: missing $SRC"; exit 1; }
grep -Evx 'Algorithm=SHA-256|[0-9A-Fa-f]{64}' "$SRC" | grep -q . && { echo "ERROR: unexpected format"; exit 1; }
[ "$(tr 'a-f' 'A-F' < "$SRC" | grep -c -x -F -f /tmp/emudhra16.txt)" = 16 ] || { echo "ERROR: missing eMudhra fingerprints"; exit 1; }
for JDK in /Library/Java/JavaVirtualMachines/*/Contents/Home \
"$HOME"/Library/Java/JavaVirtualMachines/*/Contents/Home \
/opt/homebrew/opt/openjdk*/libexec/openjdk.jdk/Contents/Home \
/usr/local/opt/openjdk*/libexec/openjdk.jdk/Contents/Home; do
[ -x "$JDK/bin/java" ] || continue
F="$JDK/lib/security/blocked.certs"
[ -f "$F" ] || F="$JDK/jre/lib/security/blacklisted.certs"
[ "$(head -n 1 "$F" 2>/dev/null)" = "Algorithm=SHA-256" ] || { echo "SKIPPED: $JDK"; continue; }
[ -e "$F.pre-emudhra" ] || cp -p "$F" "$F.pre-emudhra" || exit 1
{
echo "Algorithm=SHA-256"
{ tail -n +2 "$F"; grep -Ex '[0-9A-Fa-f]{64}' "$SRC"; } | tr 'a-f' 'A-F' | sort -u
} > "$F.tmp" && cat "$F.tmp" > "$F" && rm "$F.tmp" || exit 1
echo "$JDK: $(grep -c -x -F -f /tmp/emudhra16.txt "$F")/16; entries before: $(($(wc -l < "$F.pre-emudhra") - 1)); after: $(($(wc -l < "$F") - 1))"
done
echo "Restart all running Java applications: blocked.certs is only read when the JVM starts."
)Oracleのファイルや修正済みJDKのファイルを使う場合は、1行目をそのパスに変えてください。すべてのJDKが16/16になるはずです。/Library/Java/JavaVirtualMachinesにあるJDKには管理者権限が必要です。sudo -sで開いたシェルでスニペットを実行してください。Javaはリストを起動時にしか読み込まないため、実行中のJavaアプリケーション、IDE、サーバーを再起動する必要があります。Homebrewを更新すると、ファイルは新しいバージョンのものに置き換わります。そのバージョンが修正済みなら問題ありません。そうでなければ、スニペットをもう一度実行してください。
OpenJDKのアドバイザリは、もう1つの一時的な代替策として、「-Dcom.sun.net.ssl.checkRevocation=true -Dcom.sun.security.enableCRLDP=true」で失効確認を有効にする方法を示しています。keytool -deleteでルート証明書を削除するのは、この修正のやり方ではありません。修正はルート証明書を残し、16個の証明書をブロックします。AAA Certificate Servicesを削除すると、それに依存するすべてにも影響します。また、Dennis Jacksonのページでは、これらのルート証明書を信頼しないようにすることは一般ユーザーには推奨されないとしています。
Rust
Rustでは、修正はコンパイラーのバージョンではなく、各プロジェクトのCargo.lockによって決まります。rustls-webpki 0.103.16はブロック対象の鍵を拒否し(RUSTSEC-2026-0382)、webpki-roots 1.0.10はルート証明書emSign ECC Root CA - G3を削除しています。macOSではrustls-platform-verifierはシステムのベリファイアを使いますが、Linuxではwebpkiを使います。そのため、ここでもリスクはコンテナにデプロイするバイナリにあります。各プロジェクトで次を実行してください。
cargo tree -i rustls-webpki
cargo update -p rustls-webpki
cargo tree -i rustls-webpki更新後、「cargo tree」にはrustls-webpki v0.103.16以降が表示されるはずです。プロジェクトがwebpki-rootsを使っている場合は、「cargo update -p webpki-roots」で同じように1.0.10まで更新してください。そのうえで再ビルドしてデプロイし直します。rustupを使っている場合は、「rustup self update」で1.29.2に更新してください。
Docker
10月22日にリリースされたDocker Desktop 4.96.2は、侵害された中間CAへの信頼を取り消しています。これはDockerのCLIとデーモンの接続には適用されますが、イメージには適用されません。各イメージは独自のルート証明書のリストと、独自のバージョンのPython、Node、Java、Goを持っています。
アプリから、または「brew upgrade --cask docker-desktop」でDocker Desktopを更新し、古いルート証明書を含むレイヤーを再利用しないように、キャッシュなしでイメージを再ビルドしてください。
docker version --format '{{.Server.Platform.Name}}'
docker build --pull --no-cache -t my-image:emudhra .
docker run --rm my-image:emudhra python3 -m pip --version最後の行はPythonを含むイメージの例で、イメージの中ではpip 26.2.2以降が表示されるはずです。それ以外のイメージでは、該当する言語のテストをコンテナの中で実行してください。ベースイメージがまだ修正済みのバージョンを公開していない場合は、独自のDockerfileでディストリビューションのca-certificatesパッケージかランタイムを更新してください。
チェックリスト
- Homebrew:ca-certificates 2026-09-25_1以降。Homebrewのcurlでテストサーバーに対してテスト済み。
- システムのcurl、git、python3:/etc/ssl/cert.pemへの対応方針を決定し、記録済み。
- Node:インストール済みのすべてのバージョンが26.12.1、24.22.1、22.23.4のいずれか。
- Python:すべての仮想環境でpip 26.2.2とcertifi 2026.10.19。uv 0.13.4。
- Go:1.27.3または1.26.10。バイナリは再ビルドしてデプロイ済み。
- Java:Homebrewのkeg-onlyフォーミュラも含め、すべてのJDKが修正済みのバージョン(名前だけでなく完全なバージョン番号で確認)。更新できない場合はblocked.certsに16個のフィンガープリント(16/16)があるか失効確認を有効化済みで、Javaアプリケーションを再起動済み。
- Rust:すべてのCargo.lockでrustls-webpki 0.103.16。バイナリは再ビルド済み。
- Docker:Desktop 4.96.2以降。イメージはキャッシュなしで再ビルド済み。
- 検証を無効にする、またはルート証明書を追加する変数とオプションを確認済み。
拒否されても証明できないこと
テストで証明書エラーが出た場合、それはそのツールのそのバージョンがもう中間CAを信頼していないことを示します。同じMac上の別のツール、別の仮想環境、コンテナについては何もわかりません。また、問題が解決していなかった期間に、管理下にないネットワークを経由した接続があったかどうかの確認の代わりにもなりません。
macOSとCIでeMudhraのインシデントを収束させるには、7つのツールを1つずつ更新し、各テストの出力を日付とバージョンとともに保存してください。それが、修正が必要な場所に適用されたことを示す最もシンプルな証拠です。
参考資料
2026年10月23日に参照した資料。Linux(Debian 13)で実行し、出力を保存したもの:curl、Node、Python、Go、Java、Rustのテスト、ハッシュ指定でのpipの更新、テスト用パスに置いたJDKのコピーでの16/16の確認とblocked.certsの結合。10月23日に実機のMac(macOS 27.0.1、arm64)で読み取り専用で確認したもの:/usr/libexec/java_home -V、/Library/Java/JavaVirtualMachines、brew list --versions。macOSでは実行していないもの:brew upgrade、brew --prefix、sudo -s、スクリプト内のHomebrewのパス、/etc/ssl/cert.pem。実行していないもの:Docker。
- Dennis Jackson:テストサーバーと修正済みのバージョン
- Google Security Blog、2026/10/20
- Bugzilla 2083449:Mozillaのインシデント報告
- Mozilla Security Blog、2026/10/20
- CAによるインシデントに関する声明
- Cloudflare Blog、2026/10/20
- Python Discourse:Pythonユーザー向けの情報
- Python Insider: Python 3.15.1, 3.14.9 and 3.13.17
- pip: release notes
- Node.js 24.22.1 release notes
- golang-announce: Go 1.27.3 and 1.26.10
- Go: crypto/x509 package documentation
- OpenJDK Vulnerability Advisory, 2026-10-21
- Oracle Security Alert CVE-2026-91403
- Oracle JDK 25.0.5.0.2 release notes
- Oracle JDK 8u511 release notes (b09, 20/10/2026)
- Oracle JDK 8u511 b32 release notes (21/10/2026)
- Oracle JDK 8u511-perf-b32 release notes (21/10/2026)
- RustSec: RUSTSEC-2026-0382
- rustls-platform-verifier
- Rust Blog: Rustup 1.29.2
- Docker Desktop release notes


