flawopen.com/GitHub Actionsのセキュリティ/workflowスクリプトインジェクション
GitHub Actionsのスクリプトインジェクションはどう起き、どう防ぐ?
高権限時の影響は重大
CWE-78
CI/CD workflowのセキュリティ
かんたんに説明
Bash起動前にissueタイトルやpull requestの値をscriptへ埋め込むと、workflowがデータをshell構文に変えることがあります。名前を指示と誤解する名札プリンターのようなものです。環境変数で値を渡し、データとして使う際は展開を引用符で囲めば、Bashは値をscriptと分けて受け取ります。影響はtoken、secret、runner、イベントにも左右されます。
信頼できないコンテキストタイトル、本文、branch名、label、commit messageなどのGitHubイベント値。外部ユーザーが制御できる文字列として扱います。
式の展開GitHubはshell起動前に
${{ ... }} を評価します。run:では入力がscriptソースへ挿入されることがあります。環境変数での受け渡し
env:への割り当てはプロセスデータとして値を渡します。shell展開を引用し、evalや動的script生成を避けます。権限境界イベントとworkflowがtoken権限、利用可能なsecret、runnerアクセスを決めます。影響はjobが到達できる資源に限られます。
原因:shell解析前にデータが埋め込まれる
GitHubはrunステップのshell起動前に式を展開します。信頼できないタイトルを直接埋め込むと、shellプログラムが変わる可能性があります。env:経由の値はscript本文から分離され、引用符で囲めば通常コマンドへの引数として保たれます。ただし、後でevalや別のインタープリター、引数をコードとして扱うツールへ渡す場合は安全ではありません。GitHubはイベント値を攻撃者が制御し得る入力として扱います。
.github/workflows/triage.yml(危険な埋め込み)危険
# 危険:イベントデータが生成shell scriptの一部になる
name: Issue Triage
on:
issues:
types: [opened]
permissions:
contents: read
jobs:
triage:
runs-on: ubuntu-latest
steps:
- name: Print issue title
run: |
printf 'Title: %s\n' "${{ github.event.issue.title }}"
.github/workflows/triage.yml(データを分離)対策済み
# より安全:イベント値を環境変数で渡す
name: Issue Triage
on:
issues:
types: [opened]
permissions:
contents: read
jobs:
triage:
runs-on: ubuntu-latest
steps:
- name: Print issue title
env:
ISSUE_TITLE: ${{ github.event.issue.title }}
run: |
printf 'Title: %s\n' "$ISSUE_TITLE"
攻撃経路の概要
Step 1
利用者がイベント値を制御
公開issueやpull requestのタイトル、branch名がworkflow入力になります。
Step 2
workflowがshellソースへ埋め込む
run:内の直接的な ${{ github.event... }} はBash解析前に展開されます。
Step 3
shellが変更されたプログラムを解釈
値がshell構文を変えるとjobのプロセス権限でコマンドが動きます。引用符付き引数のままなら注入は起きません。
Step 4
jobの権限が影響を決める
侵害されたjobが触れられるのは実行に開かれた資源だけです。GITHUB_TOKEN権限、secret、runnerを確認し、issueイベントとpull_request_targetを精査します。
強化チェックリスト
- ✓信頼できない
github.event値をrun:に直接埋め込まない。env:で渡し、"$ISSUE_TITLE"のように引用します。 - ✓値を
eval、生成script、shellコマンド文字列、引数をコードやオプションとみなすツールへ渡さない。 - ✓workflowまたはjobに制限的な
permissions:を設定し、書込権限は必要なjobだけに付与します。 - ✓
pull_request_targetとworkflow_runを特権境界として扱い、信頼できないPRのコードやartifactをcheckout・build・実行しません。 - ✓信頼できない複数行データを
GITHUB_ENVやGITHUB_PATHへ書かない。GITHUB_*とRUNNER_*は保護されますが、他の値は後続stepへ影響し得ます。 - ✓third-party Actionは確認済みの完全なSHAへ固定し、隔離された使い捨てrunnerを使い、Actions workflowのCodeQLを有効にします。
一次資料
- GitHub Docs — スクリプトインジェクション
- GitHub Docs — 安全な使用のリファレンス
- GitHub Docs — pull_request_targetの安全な使用
- GitHub Docs — workflowコマンドとGITHUB_ENV
- GitHub Docs — GITHUB_TOKENの権限
関連するセキュリティトピックと分析を見る:セキュリティ総合ディレクトリ →