cmd/go: support dependency cooldown in Go tooling
要約
概要
cmd/go: support dependency cooldown in Go tooling(Issue #76485)は、サプライチェーン攻撃対策として、go get や go mod tidy が依存関係を解決する際に、公開から一定期間経過していないバージョンを無視する「依存関係クールダウン」機能をGoツールチェーンに追加するproposalです。
ステータス変更
active → hold
2026年6月24日のProposal Reviewミーティング(@adonovan, @bradfitz, @cherrymui, @griesemer, @ianlancetaylor, @neild, @rolandshoemaker 出席)にて、「まずモジュールプロキシ層でのURLパスプレフィックスによる実装を試みる」という方針が決定されました。go コマンド自体への機能追加は、プロキシ実装の実験結果を待ってから再検討することになったため、holdに移行しました。
技術的背景
現状の問題点
オープンソースのサプライチェーン攻撃が増加しており、悪意あるコードが依存パッケージに仕込まれるケースが報告されています。2025年にはGitLabがGoモジュールに対するタイポスクワッティング攻撃を検知しました。攻撃の多くは公開後短時間(数時間〜数日)で検知・対応されるという実証データがあり、10件の攻撃のうち9件は7日間のクールダウンで防御できたとされています。
Goは既にsumdb(チェックサムデータベース)とMVS(Minimum Version Selection)という二重の防御機構を持っています。
- sumdb: 既存バージョンのコンテンツ改ざんを防ぐ
- MVS: 推移的な依存関係に最新版が自動適用されることを防ぐ
クールダウンは、go get -uや@latestによる最新バージョンの取得に対して追加の防御層となる可能性があります。
提案された解決策
環境変数 GOCOOLDOWN を追加し、go get や go mod tidy が公開から指定期間未満のバージョンを無視するようにする:
GOCOOLDOWN=15d go mod tidy
これによって何ができるようになるか
クールダウンを設定することで、攻撃が検知・対応されるまでの時間的余裕を確保できます。
コード例
// Before: 最新バージョン(悪意あるコードが含まれている可能性あり)を取得
go get -u
// After: 15日以上経過した安定バージョンのみを対象に更新
GOCOOLDOWN=15d go get -u
// あるいは
go env -w GOPROXY=https://proxy.golang.org/delay/7d/
プロキシ経由のアプローチ(@rscが提案)では、既存のGoバージョンでも動作し、新しいGoリリースを待たずに実験できます。
議論のハイライト
- 実装の信頼性問題: VCSタグのタイムスタンプは攻撃者が偽装できるため、プロキシが「最初にバージョンを観測した時刻」を基準にする必要があるという指摘(@FiloSottile)。最終的にはsumdbにfetch timestampを記録することで、プロキシの嘘を検出できるという設計が議論されました。
- 段階的アプローチの採用: @rscは
proxy.golang.org/delay/{N}d/のようなURLパスプレフィックス形式を提案。/cached-only/と同様の仕組みで、GOPROXY環境変数を変更するだけで機能し、Goのリリースを待たずに実験可能。今回holdとなった理由はこのアプローチを先行実装するためです。 - 適用範囲の議論: 名指しバージョン(
go get foo@v1.2.3)にはクールダウンを適用しない方針が浮上。セキュリティ修正を即座に適用できるようにするため。go get -uなど暗黙的な最新バージョン取得にのみ適用することが望ましいとされました(@neild)。 - Go Command Working Groupの懸念: セキュリティアップデートへの対応方法、デフォルト動作の設計、既知のユーザーがいない場合の有効性について未解決という意見(@matloob)。
- プライベートモジュールへの考慮:
GOPRIVATEで自組織のモジュールをクールダウン対象外にする案が検討されました(@thepudds, @mikeschinkel)。 - リトラクションとの相互作用: クールダウンで新バージョンが見えない状態でリトラクションが宣言されると、リトラクション情報も見えなくなる問題が指摘されました(@AGWA)。