RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

あなたのCIは本当に安全?GitHub Actionsに潜むリスクと防ぎ方

こんにちは、id:takaram です。

ラクスでは全社で GitHub を利用しており、大半のプロジェクトが GitHub Actions を CI として利用しています。 GitHub Actions は、テストやデプロイまでを自動化する強力な仕組みである一方、正しく使わなければセキュリティホールとなる危険性もはらんでいます。

今回は、GitHub Actions のセキュリティについて紹介していきます。

GitHub Actions のセキュリティ

プロダクトコードのセキュリティには皆さん気をつけていると思いますが、CI/CD のコードに気を配る必要性はあまり認識されていないかもしれません。 しかし、2025年に入ってからも CI/CD 基盤を狙ったサプライチェーン攻撃が相次いでいます。

  • 3月:tj-actions/changed-files が改ざんされ、これを実行したリポジトリの GitHub Actions のビルドログにシークレット情報が出力された rocket-boys.co.jp
  • 8月:npm パッケージ Nx の GitHub Actions の設定が悪用され、不正なコードが混入したパッケージをリリース(通称 "s1ngularity" 攻撃) blog.jxck.io

これらはいずれも、CI/CD がアプリケーションと同じレベルで攻撃対象になっていることを示しています。
開発者自身が GitHub Actions のセキュリティを理解し、適切に守ることが重要です。

ありがちな侵害のパターンと対策

ここでは、よくある脆弱なパターンを4つ取り上げます。
それぞれのリスクと、すぐに実践できる対策をセットで紹介します。

1. サードパーティアクションの侵害

問題

GitHub Marketplace などで配布されている外部アクションは、メンテナーが乗っ取られたり、公開リポジトリが改ざんされると、攻撃者が不正なコードを仕込むことができます。
2025年3月に発生した tj-actions/changed-files 改ざん事件では、多数のリポジトリが影響を受けました。

タグ指定(例:@v3@v3.6.0)では、タグは後から付け替え可能であり、改ざんの影響を受けてしまいます。

対策

commit SHA で固定するのが有効です。

uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

ただし、この場合アクションの新バージョンがリリースされ、通常の機能追加やバグ修正が行われても自動では最新版が利用されないことになります。 Dependabot / Renovate を利用して適宜最新バージョンに更新するのがいいでしょう。

また、そもそもアクション自体が信頼できるものか、導入時点で確認することも重要です。アクションのコードを確認できればベストですが、せめてメンテナーや開発体制、利用実績などを確認するとよいでしょう。

2. 過剰な権限設定

問題

GITHUB_TOKEN に不要な権限が付与されていると、侵害時にリポジトリ改変やタグ作成・リリース改ざんなどの被害が発生する可能性があります。

また、secret に PAT (Personal Access Token) を設定している場合も、発行時に不要な権限を付与していると、漏洩時の被害が拡大します。

対策

ジョブごとにGITHUB_TOKENの最小限の権限を明示します。

permissions:
  contents: read
  pull-requests: read
  # 指定していない権限は`none`になる

また、上記の権限設定がされていない場合のデフォルトの権限が、リポジトリ設定から変更できます。 これはread onlyにしておきましょう。

Settings → Actions → General → Workflow permissions
→ 「Read repository contents and packages permissions」を選択

PAT を利用する際は、最低限の権限のみ与えます。 また、そもそも PAT を使わずに、GITHUB_TOKENや GitHub Apps トークンを利用できないか検討してください。

3. run 内での OS コマンドインジェクション

問題

run ステップ内で ${{ ... }} を直接展開すると、展開された値がシェルに渡されて解釈されます。 外部由来の値(PRタイトル、入力パラメータなど)に悪意のある文字列が含まれていた場合、意図しないコマンドが実行されるおそれがあります。

脆弱な例
- run: echo "${{ github.event.pull_request.title }}"

PRタイトルが Hello"; rm -rf * # のように細工されていると、シェルがそれを区切って解釈し、rmコマンドを実行してしまいます。

対策

以下のようにします。 1. 外部からの値を環境変数に設定する 2. シェルコマンド内で""で囲って使用する

- env:
    TITLE: ${{ github.event.pull_request.title }}
  run: echo "$TITLE"

${{ ... }} の直接展開は避け、必ず変数をダブルクオート付きで使いましょう。 これにより、シェルのワード分割やメタ文字解釈を防止できます。

4. curl | bash 型の危険なスクリプト実行

問題

curl https://example.com/foo.sh | bash のような形で外部スクリプトを直接実行すると、配布元サーバーや通信経路が侵害された場合に不正なスクリプトを実行させられる危険があります。

対策

  • 一度ファイルとしてダウンロードし、チェックサム検証などを行ってから実行する。
  • 可能な限り、公式パッケージマネージャ(apt, npm など)を利用する。

追加の対策

こうした安全な設定を、チーム内に浸透させ、全員が気をつけて実装するというのはなかなか難しいものです。

そこで、自動検出の仕組みが有効です。プロダクトコードに対して lint を実施するのと同様、ワークフローファイルも CI を利用して機械的にチェックしましょう。

ここでは、GitHub Actions の構成を lint できる代表的なツールを紹介します。

1. actionlint で構文・展開の安全性をチェック

actionlint は、GitHub Actions のワークフローファイルの構文チェックをしてくれるリンターです。 基本的な構文チェックに加えて、上記で紹介したrun:内の危険な${{ ... }}なども検出してくれます。

ShellCheck がインストールされている環境1であれば、run:内のシェルコマンドに対してもLintを実行してくれます。 変数をダブルクオートで囲んでいないなどの問題を検知可能です。

導入例

actionlint はビルド済みのバイナリが配布されているので、ダウンロードするだけで利用可能です。 ただし、ダウンロードしたバイナリが改ざんされていないか、チェックサムで確認しておきましょう。

env:
  ACTIONLINT_VERSION: "v1.7.8"
  ACTIONLINT_SHA256: "be92c2652ab7b6d08425428797ceabeb16e31a781c07bc388456b4e592f3e36a"
steps:
  - uses: actions/checkout@v5
  - run: |
      gh release download "${ACTIONLINT_VERSION}" -R rhysd/actionlint \
        -p 'actionlint_*_linux_amd64.tar.gz' -O actionlint.tar.gz
      echo "${ACTIONLINT_SHA256}  actionlint.tar.gz" | sha256sum -c -
      tar -xzf actionlint.tar.gz actionlint
  - run: ./actionlint

2. ghalint で権限設定やタグ指定を検査

ghalint は、permissions:の指定漏れやサードパーティアクションのタグ指定(@v3 など)を検出するツールです。 actionlint に比べて、よりセキュリティにフォーカスしたチェックを行ってくれます。

導入例

ghalint もビルド済みバイナリをダウンロードして利用可能です。 ダウンロードしたバイナリの検証はチェックサムでもいいですが、アーティファクトの構成証明も利用できます。

env:
  GHALINT_VERSION: "v1.5.3"
steps:
  - uses: actions/checkout@v5
  - run: |
      gh release download "${GHALINT_VERSION}" -R suzuki-shunsuke/ghalint \
        -p "ghalint_*_linux_amd64.tar.gz" -O ghalint.tar.gz
      gh attestation verify ghalint.tar.gz \
        -R suzuki-shunsuke/ghalint \
        --signer-workflow suzuki-shunsuke/go-release-workflow/.github/workflows/release.yaml
      tar -xzf ghalint.tar.gz ghalint
  - run: ./ghalint run

まとめ

GitHub Actions は開発を支える強力な仕組みであり、現代の開発にはなくてはならないものです。しかし同時に、攻撃者にとってのターゲットにもなり得ます。 設定ミスや依存先の侵害が攻撃につながる以上、CI/CD もアプリケーションと同じように守る必要があります。

今回紹介した対策を徹底し、安全に CI/CD を実行していきましょう!


  1. GitHub-hosted runner のubuntu-24.04などには ShellCheck がデフォルトでインストールされています。
Copyright © RAKUS Co., Ltd. All rights reserved.