skeleton/stepX/*.go
のTODOコメントを修正して実装しますsolution/stepX/*.go
と比較して理解を深めます各ステップのコードを修正したら、以下のコマンドで動作を確認してください。 GOTOOLCHAIN
環境変数で指定しているGo
のバージョンは各ステップの指示に従ってください。
GOTOOLCHAIN=go1.xx.yy go run ./skeleton/stepX
このステップでは、Go
のビルドタグ(build constraint)を悪用した時限爆弾攻撃の仕組みを学びます。将来のGo
バージョンで実行される悪意のあるコードを仕込む手法と、それが何故危険なのかを理解します。
ビルドタグは、特定の条件下でのみファイルをビルドに含めるための仕組みです。
//go:build go1.25
package main
func init() {
panic("This code runs only with Go 1.25 or later")
}
主な用途として以下があります。
//go:build windows
)//go:build go1.18
)//go:build debug
)GOTOOLCHAIN
環境変数GOTOOLCHAIN
環境変数を使用すると、特定のGoバージョンでコードを実行できます。
$ GOTOOLCHAIN=go1.24.6 go run . # Go 1.24.6で実行
$ GOTOOLCHAIN=go1.25.1 go run . # Go 1.25.1で実行
Go 1.21
以降、この機能により必要に応じて新しいGo
バージョンが自動的にダウンロードされます。
悪意のある開発者は、将来のGo
バージョンでのみ実行される悪質なコードを仕込むことができます。
//go:build go1.25
package main
func init() {
// 将来のバージョンでのみ実行される悪意のあるコード
panic("Time bomb activated!")
}
この攻撃の特徴は次の通りです。
Go
バージョンで悪意のあるコードが実行されるGo
バージョンでは該当ファイルがビルドされないため、テストで発見しにくい重要な概念
GOTOOLCHAIN
環境変数により任意のGoバージョンで実行可能このステップでは、ビルドタグを使った時限爆弾を作成し、その動作を確認します。
skeleton/step1/util.go
を修正して、次の要件を満たしてください。
実行例:
# Go 1.24では正常実行(util.goが読み込まれない)
GOTOOLCHAIN=go1.24.6 go run ./skeleton/step1
# Go 1.25では panic が発生(util.goが読み込まれる)
GOTOOLCHAIN=go1.25.1 go run ./skeleton/step1
GOTOOLCHAIN
環境変数の役割と使い方を説明できますか?このステップでは、ビルドタグが静的解析ツールに与える影響を学びます。ビルドタグによりファイルが条件付きでビルドされるため、静的解析も非対称になり、潜在的な問題を見逃す可能性があることを理解します。
静的解析ツール(go vet
、govulncheck、Google Capslockなど)は、現在のビルド環境でコンパイル対象となるファイルのみを解析します。
# Go 1.24では util.go は解析対象外
$ GOTOOLCHAIN=go1.24.6 go vet ./skeleton/step2
# エラーが検出されない
# Go 1.25では util.go も解析対象
$ GOTOOLCHAIN=go1.25.1 go vet ./skeleton/step2
# エラーが検出される
これにより、将来のバージョンでのみ実行される脆弱なコードや問題のあるコードが静的解析で見逃される危険性があります。
ビルドタグ付きファイルを検出するには、専用のツールが必要です。
gostaticanalysis/buildtagは、ビルドタグ付きファイルを検出・解析するツールです。
$ go install github.com/gostaticanalysis/buildtag/cmd/buildtag@latest
$ buildtag ./...
Go標準ライブラリのgo/build/constraint
パッケージを使用してビルドタグを解析できます。
import "go/build/constraint"
// ビルドタグの解析例
expr, err := constraint.Parse("//go:build go1.25")
if err != nil {
log.Fatal(err)
}
// expr.Eval(map[string]bool{"go1.25": true}) // true
重要な概念
このステップでは、ビルドタグが静的解析に与える影響を確認します。
skeleton/step2/util.go
を修正して、次の要件を満たしてください。
fmt.Printf
のフォーマット文字列を意図的に間違える(%d
を%s
に変更)go vet
のprintf
アナライザーがエラーを検出するようにする実行例:
# Go 1.24では util.go が解析されないためエラーなし
$ GOTOOLCHAIN=go1.24.6 go vet ./skeleton/step2
# Go 1.25では util.go が解析されエラーが検出される
$ GOTOOLCHAIN=go1.25.1 go vet ./skeleton/step2
./skeleton/step2/util.go:9:2: Printf format %s has arg 100 of wrong type int
go/build/constraint
パッケージの役割を説明できますか?GOTOOLCHAIN
環境変数により任意のGoバージョンでの実行が可能go vet
コマンドも同様の制限を受けるgostaticanalysis/buildtag
ツールを使ってビルドタグの検出を試す