Go の緊急セキュリティ更新 Go 1.27.3 と Go 1.26.10(2026年10月19日、URGENT トラック)は、Go 脆弱性 CVE-2026-111943 への対処として、crypto/x509 に8件の中間CAの鍵の拒否リストを足しました。修正コミットをタグから取り出して読み、拒否のしかたを Go 1.27.3 のソースでテストして確かめました。修正前のバージョンでビルドしたバイナリは問題の中間CAを信頼したままで、修正版で作り直すと、この中間CAを使う相手とはつながらなくなります。

TWO EFFECTS2つの影響

古いバイナリは信頼したまま、作り直すとつながらない相手が出る

修正前の版でビルド

1.27.2・1.26.9 以前

  • 8件の中間CAを信頼したままOS のルートがたどれれば検証が通る
  • 失効も確かめないVerify は CRL・OCSP を見ない

1.27.3 / 1.26.10 で作り直す

crypto/x509 が鍵で拒否

  • 8件の鍵を含むチェーンを捨てる独自のルートを渡しても同じ
  • 相手が使っていれば接続失敗x509: no valid chains built
出典: golang/go コミット 90617fb7(2026-10-19)を本記事で読み、テストで確認

30秒でわかる CVE-2026-111943(2026-10-21時点)

  • ・対象:Go で書かれ、TLS で外につなぐか、証明書を検証するプログラム。Go の発表は認証局の名前を出していない。Mozilla などは eMudhra(emSign)の中間CAだとしている
  • ・変わったこと:チェーンのどこかに8件の鍵(公開鍵情報の SHA-256)を含むと、検証は失敗する。独自のルートを渡しても弾かれ、GODEBUG での無効化もできない
  • ・影響は2つ:(a) 修正前の版でビルドしたバイナリは信頼したまま (b) 作り直すと、この中間CAを使う相手に x509: no valid chains built でつながらない
  • ・直し方:1.27.3 / 1.26.10 以上でビルドし直して、配り直す。コンパイラを入れ替えるだけでは、動いているバイナリは変わらない

まずやること(立場別)

  • ・Go のサービスを作って配っている:作り直す前に、接続先の証明書チェーンを下の③で確かめる。そのうえでビルドの版を上げ、作り直して配り直す
  • ・Go 製のツールを使うだけ:配布元が修正版でビルドした版を出したか確かめ、出ていれば入れ替える。手元のバイナリの版は go version にパスを渡せば分かる
  • ・eMudhra の証明書でサーバーを公開している:認証局に、別の中間CAからの発行し直しを相談する。修正版の Go で作り直した利用者からはつながらなくなる

今回の件はサプライチェーンのうち「信頼の起点」が揺らいだ例で、依存部品の管理全体はサプライチェーン攻撃とは|手口・防御ツール比較・npm 12の新機構まで実践解説にまとめている。

Go 脆弱性 CVE-2026-111943 のタイムライン(10月17日〜20日)

報告から Go の修正版の公開まで、およそ2日でした。日時は出典の書き方に合わせ、Go のコミット時刻は米太平洋時間(PDT)で書きます。

日時 出来事 出典
10月17日(土) 研究者の報告が Chrome Root Program に届く(18:05 UTC)。Mozilla にも報告が入る 報道(The Hacker News)が引く Chrome と Mozilla の説明
10月17日 Firefox は OneCRL で8件をブロック。Chrome は CRLSet で TLS 用の中間6件の鍵をブロック Mozilla のブログ/Chrome は報道
10月18日 Python の certifi 2026.10.18 が emSign のルート4件を外す certifi のコミット 5cb238c
10月19日 Go が修正をコミット(14:20 PDT)し、1.27.3 と 1.26.10 を公開。certifi 2026.10.19 は影響の無い3件を戻す golang/go のコミット・リリース履歴/certifi のコミット 662df63
10月20日 Mozilla がブログで公表。NSS 3.131.1 が emSign のルート3件を外す。Go のセキュリティポリシーは URGENT トラックの例にこの公開を挙げる Mozilla のブログ・NSS のリリースノート・golang/website

原因は出典ごとに読み分ける

原因と経緯は、出典によって書き方が違います。鍵の生成に欠陥があったのか、侵入されたのかは、本記事の時点で公式に確定した説明がありません。

出典 書いていること
Go(コミット・issue #82345) 認証局の名前を出さず、issue の題は「特定の認証局に関するセキュリティ上の懸念への緩和策」。コミットは「SPKI の SHA-256 で特定した中間を、Verify が返すチェーンから外す」とだけ書く
Mozilla のブログ eMudhra の中間証明書8件の秘密鍵が compromise(危殆化)した、と書く
Mozilla のバグ報告(報道が引く要旨) 報告者の方法を知らないまま Mozilla 自身も鍵を復元でき、鍵の生成のしかたに欠陥があったとみている
報道 「侵害」「鍵の漏えい」「弱い鍵」と書き方が分かれる

本記事は、鍵がどう作られたか、誰が鍵を持っているかを推測しません。

crypto/x509 で何が変わったか(中間証明書8件の鍵を拒否)

修正は go1.27.3 タグの直前のコミット 90617fb7(1.26 系は aa64342a、開発版は 7f86f957)です。親は go1.27.2 のタグで、間に別の変更はありません。変えたファイルは verify.go・root_darwin.go・root_windows.go の3つ、追加は42行です。1.27 系と 1.26 系で、8件のハッシュは同じでした。

どこで弾くか

verify.go に distrustedSPKIHashes という一覧(8件)と、チェーンの中の証明書を1枚ずつハッシュして照らし合わせる関数が足されました。

・Certificate.Verify が候補のチェーンを組んだあと、キー用途やポリシーの検査と同じ場所で、8件のどれかを含むチェーンを候補から捨てる
・中間CAだけでなく、末端の証明書やルートもハッシュの対象になる
・候補が残らなければ x509: no valid chains built を返す。crypto/tls を通すと tls: failed to verify certificate: x509: no valid chains built になる
・macOS と Windows では OS の検証機能を呼ぶ経路があり、そこで返ったチェーンにも同じ照合をかける
・8件を通らない別の経路のチェーンが組めれば、検証は通る

GODEBUG の設定や環境変数を読む処理は、この変更に入っていません。コメントにも認証局の名前はなく、ハッシュが並ぶだけです。テストは追加されていませんでした。

テストで確かめた挙動

8件の鍵を持つ証明書は手元で作れません。そこで Go 1.27.3 のソースのコピーに、パッケージ内のテストを1本足しました。自作のルート、中間(名前は「Test DV TLS CA - G3B」)、末端の3段を作り、中間の SPKI ハッシュを一覧に足して Verify を呼びます。

条件 結果
一覧に足す前(独自のルートを渡す) 検証が通る
中間のハッシュを一覧に足したあと(独自のルートを渡す) x509: no valid chains built
中間そのものをルートとして渡す x509: no valid chains built

go1.27.2 のソースには、この一覧そのものがありません。

攻撃者の前提

攻撃者が持つもの 修正前の版でビルドしたバイナリ 修正版で作り直したバイナリ
8件のどれかの秘密鍵と、通信の途中に入れる位置(同じネットワーク、DNS の書き換えなど) 信頼しているルートまでたどれれば、偽の証明書を本物として受け入れうる チェーンが捨てられ、接続しない
秘密鍵だけ(通信の途中に入れない) 直接のなりすましは難しい 同じ

Verify のコメントには「失効の確認はしない」とあり、認証局が証明書を失効させても Go の検証は止まりません。報道によれば、一部の中間は Sectigo のルートからもクロス署名されていました。OS の信頼ストアから emSign のルートを外しても、別の経路が残りえます。鍵そのもので弾く今回の方式なら、その経路も止まります。

8件の名前は、Mozilla のバグ報告と報道が次のように挙げています。Go のコードにはハッシュしかないため、名前とハッシュの対応は本記事では確かめていません。

・EM DV TLS CA - G3B / G3C
・EM EV TLS CA - G3B / G3C
・EM OV TLS CA - G3B / G3C
・EM OV CS CA - G3B / G3C(コード署名用)

自分が対象か確かめる:go version・go.mod・相手の中間証明書

WHERE TO LOOK確認の順番

ビルドした版と相手のチェーンを分けて確かめる

  1. ビルドに使う版

    go version と go.mod・CI・Dockerfile の版

  2. ビルド済みのバイナリ

    go version <ディレクトリ> で1本ずつ

  3. 相手の証明書チェーン

    鍵の SHA-256 を8件と照合

出典: 本記事のコマンド(2026-10-21 に自作のバイナリ・リポジトリ・証明書で陽性/陰性を確認)

3つとも読み取りだけです。自作のバイナリ・リポジトリ・証明書で、拾うべきものを拾い、無いときは何も出ないことを確かめました。

① ビルド済みのバイナリの版

go version にディレクトリを渡すと、中の Go のバイナリごとにビルドした版を出します。Go 以外のファイルは飛ばします。下は修正版より古いものだけを出す形です。

# 調べるディレクトリを自分の配置先に置き換える(例: /usr/local/bin)
dir="./bin"
go version "$dir" | awk '{
  ver = $NF; sub(/^go/, "", ver); split(ver, v, ".")
  minor = v[2] + 0; patch = v[3] + 0
  if (minor < 26 || (minor == 26 && patch < 10) || (minor == 27 && patch < 3))
    print "作り直しが必要:", $0
}'

1.24.7・1.26.10・1.27.2・1.27.3 でビルドした4本と Go 以外のファイル1つを置くと、1.24.7 と 1.27.2 の2本だけが出ました。修正版の2本だけのディレクトリでは何も出ません。読む側の go の版は問わず、1.24.7 で 1.27.3 のバイナリの版を読めました。

この結果は「ビルドに使ったバージョン」の確認で、影響の判定ではありません。古いバージョンでも TLS で外につながないプログラムなら、実際の影響は小さいはずです。新しいバージョンでも、独自の検証処理を持つプログラムは別に見る必要があります。コンテナの中のバイナリはイメージから取り出してから渡してください。

② go.mod・CI・Dockerfile の版

git fetch --all --prune
git grep -n -E '^(go|toolchain) ' -- '*go.mod'
git grep -n -E 'go-version|FROM golang:' -- '*.yml' '*.yaml' '*Dockerfile*'

go 1.27.0・toolchain go1.27.2・go-version: "1.27.2"・FROM golang:1.26.9 を置いたリポジトリでは全部の行が出て、何も無いリポジトリでは何も出ませんでした。

出た行の読み方には注意が要ります。

・go の行は言語の最低バージョンで、実際にビルドするバージョンとは限らない
・toolchain の行は、GOTOOLCHAIN が既定の auto なら、手元より新しいときにそのバージョンを取ってきて使う。GOTOOLCHAIN=local の CI では無視される
・FROM golang:1.27 のような付け方は、イメージを取り直したときに中身が変わる

grep で何も出なくても、バージョンを決めている場所が無いとは限りません。

③ 相手のサーバーの中間証明書と鍵のハッシュ

接続先がどの中間CAを使っているかは、サーバーが送ってくる証明書を1枚ずつ取り出し、公開鍵情報の SHA-256 を8件と照らせば分かります。8件は Go 1.27.3 の verify.go からそのまま写しています。

# 自分のホスト名とポートに置き換える
host="www.example.com"; port=443

# Go 1.27.3 の crypto/x509/verify.go にある8件(SubjectPublicKeyInfo の SHA-256)
cat > distrusted.txt <<'LIST'
ebed6475c2c2d80fcb199f3fe8dd6e6b3ce60b77eb15d4e42c3dec0c6f5b5105
49dd353dc2b919a3770645117d0e60c16115e7d1bc259eefe734b00ea434fe5f
e0254c7fcdc265e2f0f8a428dabb75ab4ae039b4872d62f5ee57f0877d5a8a41
5c0660a2b164910d8ff589c18e14552e9e0ec237dcefe2cb736d41a4811f81a0
43bffa19d6ef651451f6841e019931e96f6f2eaeff28ab4b6f1ce4576de2717b
63ecefee431d49523bc1136c4e72d0206a477086caf606cd5cf025686c109cf8
ec4ffa1ad0ac88081314b7aaffef6a91f97cd57291bb5ba686c5415f5eb4f6b6
92c063d67e8f14db71d288e11266ffdaf69cbf115f7bab14f3bc2f68d25e0e30
LIST

# サーバーが送ってくる証明書を1枚ずつファイルに分ける(前回の分は消す)
rm -f cert*.pem
openssl s_client -connect "$host:$port" -servername "$host" -showcerts </dev/null 2>/dev/null \
  | awk '/-----BEGIN CERTIFICATE-----/{n++; f=1} f{print > ("cert" n ".pem")} /-----END CERTIFICATE-----/{f=0}'

# 1枚ごとに subject・issuer と SPKI の SHA-256 を出し、拒否リストと照合する
for c in cert*.pem; do
  spki=$(openssl x509 -in "$c" -pubkey -noout | openssl pkey -pubin -outform DER | openssl dgst -sha256 -r | cut -d' ' -f1)
  openssl x509 -in "$c" -noout -subject -issuer
  echo "spki_sha256=$spki"
  grep -q -x "$spki" distrusted.txt && echo "!! 拒否リストの鍵: $c"
done

自作のルート・中間・末端の3段を手元の openssl s_server で出して確かめました。実在の8件のリストでは何も当たらず、中間のハッシュをリストに足すと !! 拒否リストの鍵: cert2.pem が出ました。

何も出なくても、影響が無いとは限りません。見ているのはサーバーが送ってきた証明書だけです。サーバーが中間を送らない構成や、クライアントが別の経路でチェーンを組む場合は、この手順だけでは判断できません。最後は修正版でビルドしたプログラムから実際につないで確かめてください。

対処:Go 脆弱性の修正は Go バージョンアップと作り直し・配り直しまで

REBUILD AND SHIP直し方

コンパイラを上げただけでは動いているバイナリは変わらない

  1. 版を上げる

    go.mod・CI・FROM

  2. 作り直す

    go build・イメージ

  3. 配り直す

    デプロイ・差し替え

  4. 接続を確かめる

    失敗は相手に依頼

出典: go.dev リリース履歴(1.27.3 / 1.26.10・2026-10-19)

Go のセキュリティ修正は標準ライブラリに入るので、依存モジュールの更新では直りません。直るのはビルドに使うツールチェーンの側です。

・バージョンを上げる:モジュールで go get [email protected] を実行すると、go.mod の toolchain 行が go1.27.3 になる(手元が 1.27.2 でも、この行があれば auto のときは 1.27.3 で動いた)。1.26 系に留めるなら 1.26.10
・CI とイメージを揃える:setup-go の go-version、Dockerfile の FROM golang: を同じ版にする
・作り直して配り直す:ビルドし直したバイナリとイメージを、本番・配布物・社内ツールまで入れ替える。①でもう一度確かめる
・1.25 以前:1.25 系の新しいタグは 8月19日の 1.25.14 が最後で、修正版はない。1.26.10 以上に移す

作り直したあと、相手によっては x509: no valid chains built でつながらなくなります。拒否はコードに直接入っていて、元に戻す設定はありません。修正前のバージョンでビルドし続けると、問題の中間CAを信頼したままになります。

・相手のサーバーの場合:③で確かめた結果を添えて、別の認証局(または別の中間CA)の証明書への切り替えを依頼する
・自社のサーバーの場合:eMudhra 以外の認証局から発行し直す。更新の自動化は Certimateとは|SSL証明書の発行・配置・更新を自動化するセルフホストACMEツールを実測が参考になる
・クライアント証明書(相互TLS)やコード署名:Go のサーバーが検証するクライアント証明書や、Go で検証するコード署名も同じ照合を通る。発行元の中間CAを確かめる

修正版をすぐ配れないサービスの手当てとしては、仮想パッチとは|修正版を当てるまでの数日をWAFで稼ぐ手順と、IDORやカーネルなどWAFでは守れない脆弱性の考え方が使えます。ただし今回は、クライアント側の証明書の検証の話なので、WAF では守れません。依存部品の脆弱性をどの順で直すかは、npm audit の結果はどれから直す?依存関係の脆弱性を到達性・EPSS・KEVで仕分ける実践手順と同じく「どこで実際に使っているか」から決めます。Go 製の部品が絡む別の脆弱性は、AWS Advanced Go Wrapperの権限昇格脆弱性 CVE-2026-11401|影響範囲・対処・検知方法で扱っています。

影響範囲:ブラウザ・Python・OS の信頼ストアの対応

Go 以外のソフトは、それぞれの信頼ストアの更新で対応しています。確かめられた範囲を表にします。

製品 何をしたか 確かめた出典
Go 1.27.3 / 1.26.10 で、8件の鍵を含むチェーンを検証で捨てる golang/go のコミットを読み、テストした
Firefox OneCRL で8件をブロック。更新や再起動なしで届く Mozilla のブログ
NSS 3.131.1(10月20日)で emSign ECC Root CA - G3、emSign Root CA - C1、emSign ECC Root CA - C3 を外す nss-dev/nss の NSS_3_131_1_RTM タグの certdata.txt
Python(certifi) 2026.10.18 で emSign のルート4件を外し、2026.10.19 で3件を戻した。emSign ECC Root CA - G3 は外れたまま certifi のコミット 5cb238c・662df63
Chrome CRLSet で、TLS 用の中間6件の鍵をブロック 報道。Chrome の一次の発表は本記事では確かめていない
Apple・Microsoft 報道は信頼を外したとしている 各社の一次の発表は本記事では確かめていない

報道は、問題の中間の上にあるルートを「emSign Root TLS CA - G3」「emSign Root CS CA - G3」と書いています。NSS と certifi が外したのは上の名前で、両者の関係(クロス署名など)は本記事では確かめていません。

Go のプログラムがどの信頼ストアを見るかは、OS によって違います。

・Linux:Go は OS の証明書の束(/etc/ssl/certs など)を読み、検証は自前で行う。配布元が束を更新して emSign のルートが外れると、古い版のバイナリでも直接の経路は x509: certificate signed by unknown authority で止まる。クロス署名の経路は残りうるので、作り直しは要る
・macOS・Windows:OS の検証機能を呼ぶので、OS 側が信頼を外せば古いバイナリにも効く。修正版はさらに8件の照合を重ねる
・Python:requests などは certifi の束を使い、標準の ssl は既定で OS の信頼ストアを見る。どちらを使っているかで更新する先が変わる

参照ソース

・golang/go コミット 90617fb7(release-branch.go1.27) — 拒否リスト8件と照合の追加(2026-10-21時点)
・golang/go コミット aa64342a(release-branch.go1.26) — 1.26.10 の同じ修正
・golang/go コミット 7f86f957(開発版)
・Go Release History — go1.27.3 / go1.26.10(2026-10-19、crypto/x509 のセキュリティ修正)
・[security] Go 1.27.3 and Go 1.26.10 are released(golang-announce)
・golang/go issue #82345 — crypto/x509: mitigation for security concerns with a specific Certificate Authority
・Go Security Policy — URGENT トラックの説明
・Protecting Firefox users following the compromise of eMudhra intermediate certificates(Mozilla Security Blog)
・Mozilla Bugzilla 2083449 — Private key compromise of eMudhra Intermediate Certificates
・NSS 3.131.1 release notes
・certifi コミット 5cb238c(Remove emsign)・662df63(Restore unaffected emSign roots)
・The Hacker News:Go Issues Emergency Update Blocking eMudhra Certificate Keys
・Threat Landscape:Go 1.27.3 Blocks Eight eMudhra Intermediate CAs
・Cyber Kendra:Go Blocks Compromised eMudhra CA Keys in Emergency Update
・QuadMeUp:Go Blocks Eight eMudhra Intermediate Certificates in crypto/x509 Security Fix