サードパーティ Action の乗っ取りによるサプライチェーン攻撃 #
この GitHub Actions の定義にはセキュリティの脆弱性があります。
name: test
on: pull_request
jobs:
my-job:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6actions/checkout@v6 のところです。例えばいま v6 の最新版が v6.1.2 だとします。
actions/checkout の開発権限が乗っ取りに合い、コードに悪意のあるコードが混入し、v6.1.3 としてリリースされたとします。
v6 という指定は、v6.1.3 が公開された時点で v6.1.3 を参照します。その結果、あなたの GitHub Actions の定義は悪意のあるコードを実行してしまいます。
では actions/[email protected] と指定しておけば安全かというとそうでもありません。タグは付け替えが可能なため、悪意のある開発者は悪意のあるコードを含むコミットに対し v6.1.2 のタグを付け、既存のタグを上書きすることで、やはりあなたの定義は悪意のあるコードを実行してしまいます。
これはいわゆるサプライチェーン攻撃の一種です。
GitHub Actions におけるこの脆弱性は SHA ピンニング(SHA pinning)で回避できます。SHA ピンニングとは、GitHub Actions の定義において、タグではなくコミット SHA を指定することです。
具体的には以下のように定義します。
name: test
on: pull_request
jobs:
my-job:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10df4cb1c069e1874edd31b4311f1884172cec0e10 とは actions/checkout の v6.0.0 のコミットハッシュです。結果的には actions/[email protected] と同じ意味になります。
ただし、タグと異なりコミットハッシュは後からの付け替えができません。そのため、悪意のある開発者が悪意のあるコードを含んだバージョンを公開したとしても、あなたの定義は悪意のあるコードを実行することはありません。
Action の呼び出しは SHA pinning を推奨 #
すべて SHA pinning で書くことが推奨です。
しかし、手作業で SHA pinning するのは大変です。そこで pinact というツールを使うと便利です。
- suzuki-shunsuke/pinact
- https://github.com/suzuki-shunsuke/pinact
CLI ツールとなっており、実行することで GitHub Actions のすべての Action のバージョンを SHA pinning してくれます。
まずはなにかしらの方法で pinact をインストールします。Homebrew でインストールする場合は以下のコマンドです。
brew install pinactそうすると pinact コマンドが使えるようになります。pinact --help でヘルプが表示されます。
pinact --help
NAME:
pinact - Pin GitHub Actions versions. https://github.com/suzuki-shunsuke/pinact
USAGE:
pinact [global options] [command [command options]]
VERSION:
4.1.0
COMMANDS:
init Create a pinact configuration file if it doesn't exist
run Pin GitHub Actions versions
migrate Migrate .pinact.yaml
token Manage GitHub Access token
version Show version
help, h Shows a list of commands or help for one command
completion Output shell completion script for bash, zsh, fish, or Powershell
GLOBAL OPTIONS:
--log-level string log level [$PINACT_LOG_LEVEL]
--config string, -c string configuration file path [$PINACT_CONFIG]
--help, -h show help
--version, -v print the versionさて SHA pinning ですが、pinact run を実行するだけです。
pinact run実行後、以下のように GitHub Actions の定義が SHA pinning されます。
.github/workflows/my-ci.yml:31
- uses: actions/checkout@v6
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
.github/workflows/my-ci.yml:34
- uses: actions/setup-node@v6
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0その他参考 #
- 1,000 人規模での GitHub Actions サプライチェーンリスク対策 — HACK The Nikkei
- https://hack.nikkei.com/blog/advent20251210/