TL;DR
- 2025 年 2 月、Module Proxy のキャッシュが更新されない性質を悪用したタイポスクワッティングが見つかった。
- MVS、go.sum、Module Proxy はこの攻撃を防げないので、依存の名前を手で書かないといった対策が必要である。
内容
実際に起きた攻撃
2025 年 2 月、3 年以上潜んでいた悪意あるパッケージが見つかった。本物の github.com/boltdb/bolt に似せた github.com/boltdb-go/bolt という名前で公開された、タイポスクワッティングである。
攻撃は次の流れで行われた。まず、攻撃者が悪意のあるコードを GitHub に公開する。誰かが go get すると、Module Proxy(Go Module Mirror)が悪意のあるバージョンをキャッシュする。キャッシュは一度作られると更新されない(配布の不変性)。その後、攻撃者は GitHub のタグをクリーンなコードに書き換える。こうして、GitHub 上のコードはきれいに見えるのに、Module Proxy からは難読化されたバックドア入りのコードが配布され続ける。
モジュールの仕組みでは防げない
MVS は予期しないバージョンが入るのを防ぐ。go.sum はモジュールの改ざんを検出し、整合性を検証する。go.sum の検証には Checksum Database(sum.golang.org)が使われ、Merkle tree が採用されている。Module Proxy は、配布されたパッケージが変わらないことを保証する。しかし、どれもタイポスクワッティングには無力である。
対策
依存パッケージの名前は手で書かず、補完に任せる。gopls の matcher は CaseSensitive にしておく。Lint では、gci で import を整理して見やすくする。
go mod verify や go mod tidy は悪意のあるモジュールを検出できないので、今回のケースには効かない。govulncheck や nancy は既知の脆弱性をチェックするツールなので、これも検出できない。
キーワード
- サプライチェーン攻撃
- タイポスクワッティング
- Go Module Mirror
- MVS
- go.sum
- Checksum Database
- Merkle tree
- gopls
- govulncheck