🚨

GitHub Actions の uses でメジャーバージョンを参照するのはリスク

2021/05/15に公開

概要

古いドキュメントで推奨されていたせいかメジャーバージョンが参照されることも多い GitHub Actions の uses ですが、サードパーティアクションにおいてはあまり良くないと思うので記事にしました。

サードパーティアクションの使い方

まずは前提となるサードパーティアクションの使い方です。
https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsuses
(ページ内リンクの都合上英語ドキュメントにリンクしていますが上部で日本語ドキュメントへ切り替えられます。)

uses の使用例
steps:    
  # 特定のコミットを参照
  - uses: actions/setup-node@c46424eee26de4078d34105d3de3cc4992202b1e
  # リリースのメジャーバージョンを参照
  - uses: actions/setup-node@v1
  # リリースのマイナーバージョンを参照
  - uses: actions/setup-node@v1.2
  # ブランチを参照
  - uses: actions/setup-node@main

Git ref、SHA、またはDockerタグ番号を指定して、使用しているアクションのバージョンを含めることを強く推奨します。 バージョンを指定しないと、アクションのオーナーがアップデートを公開したときに、ワークフローが中断したり、予期せぬ動作をしたりすることがあります。

  • リリースされたアクションバージョンのコミットSHAを使用するのが、安定性とセキュリティのうえで最も安全です。
  • 特定のメジャーアクションバージョンを使用すると、互換性を維持したまま重要な修正とセキュリティパッチを受け取ることができます。 ワークフローが引き続き動作することも保証できます。
  • アクションのデフォルトブランチを使用すると便利なこともありますが、別のユーザが破壊的変更を加えた新しいメジャーバージョンをリリースすると、ワークフローが動作しなくなる場合があります。

この記事で「メジャーバージョンを参照」と言っているのは使用例の2番目、引用した注意書きのリスト2番目を指します。
マイナーバージョンは指している SHA が変わらず、メジャーバージョンは最新のマイナーバージョンが指している SHA へ都度変更されるものとします。

GitHub 上のエディタで Marketplace からコードをコピーした場合、デフォルトはマイナーバージョンを参照するようになっていますがコメントで SHA を参照する方法も記載されています。

- name: Tweet action
  # You may pin to the exact commit or the version.
  # uses: snow-actions/tweet@d78243e356603937ebc80dd531d9f0e071adc3e3
  uses: snow-actions/tweet@v1.1.0

なぜメジャーバージョン参照ではダメなのか

安定性セキュリティの観点からおすすめしません。

安定性

  • 特定のメジャーアクションバージョンを使用すると、互換性を維持したまま重要な修正とセキュリティパッチを受け取ることができます。 ワークフローが引き続き動作することも保証できます。

自動的に修正が適用され一見セキュリティの向上に繋がるように見えますが、自動的に修正が加わるということは裏を返せば修正に不具合があった場合 「何もしてないのに壊れた」 が発生します。
これはブランチを参照するのと五十歩百歩であることを意味します。

SHA または(指している SHA を変更しないことを前提とした)マイナーバージョンの参照であればこの問題は発生しません。

セキュリティ

https://docs.github.com/ja/actions/learn-github-actions/security-hardening-for-github-actions#using-third-party-actions

  • アクションを完全なコミット SHA にピン止めする

特定の SHA にピン止めすると、有効な Git オブジェクトペイロードに対して SHA-1 衝突を生成する必要があるため、悪意のある人がアクションのリポジトリにバックドアを追加するリスクを軽減できます。

  • 作成者を信頼できる場合に限り、アクションをタグにピン止めする

コミット SHA に対するピン止めが最も安全なオプションですが、タグを指定する方が便利で広く使用されています。 タグを指定する場合は、アクションの作成者が信頼できることを確認してください。 GitHub Marketplace の「Verified creator」バッジは便利な判断材料で、 GitHub で身元が確認されたチームによって作成されたアクションであることを示しています。 作者が信頼できる場合でも、このアプローチにはリスクがあることに注意してください。悪意のある人がアクションを保存しているリポジトリにアクセスすると、タグが移動または削除される可能性があります。

ブランチもタグもリポジトリの書き込み権限を持っていれば指している SHA を任意に変更ができます。
リポジトリのオーナーが悪意を持って変更した場合はもちろん、意図せず悪意のある変更を受け入れてしまった場合にもセキュリティが侵害されることになります。
SHA の参照であればこの問題は発生しないと言ってよいでしょう。

  • アクションのソースコードを監査する

アクションが想定どおりにリポジトリとシークレットのコンテンツを処理していることを確認します。 たとえば、シークレットが意図しないホストに送信されていないか、または誤ってログに記録されていないかを確認します。

いずれの参照方法でもサードパーティ製である以上ソースコードを確認しておくことは必要です。
信用に足る作成者であれば省略はできるかもしれません。

マイナーバージョンでもセキュリティを担保

マイナーバージョンを参照した場合、安定性の確保ができる代わりに重要な修正やセキュリティパッチを自動で受け取ることができなくなります。
これはこれでセキュリティリスクなので Dependabot を使ってアップデートしましょう。
PR で送られてくるので CI をパスするか確認してマージできます。
https://zenn.dev/snowcait/articles/ae7511ea14051e98a5da

SHA を参照しているものは流石に更新してくれないようでした。

まとめ

利便性とのトレードオフではあるので(特にファーストパーティアクションなど)リスクを許容できる場合はメジャーバージョンを参照しても構わないと思いますが、一般的には マイナーバージョン (&Dependabot)または コミット SHA を参照しておく方が安全なのではないかと思います。

参照 安定性
(壊れない)
セキュリティ
パッチ
セキュリティ
(悪意ある変更)
コミット SHA ×
マイナーバージョン&Dependabot
マイナーバージョン ×
メジャーバージョン ×
ブランチ × ×

Discussion