# Gh Actions - Context Script Injections

{{#include ../../../banners/hacktricks-training.md}}

## リスクの理解

GitHub Actions はステップが実行される前に ${{ ... }} の式をレンダリングします。レンダリングされた値はステップのプログラムに貼り付けられます（run ステップならシェルスクリプト）。run: 内に信頼できない入力を直接埋め込むと、攻撃者がシェルプログラムの一部を制御でき、任意のコマンドを実行される可能性があります。

Docs: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions and contexts/functions: https://docs.github.com/en/actions/learn-github-actions/contexts

重要なポイント:
- レンダリングは実行前に行われます。run スクリプトはすべての式が解決された状態で生成され、その後シェルで実行されます。
- 多くのコンテキストは、トリガーイベント（issues、PRs、comments、discussions、forks、stars など）に応じてユーザーが制御するフィールドを含みます。詳細は untrusted input reference を参照してください: https://securitylab.github.com/resources/github-actions-untrusted-input/
- run: 内のシェルのクォートは信頼できる防御策ではありません。インジェクションはテンプレートのレンダリング段階で発生するため、攻撃者はクォートを破ったり、巧妙な入力で演算子を注入したりできます。

## 脆弱なパターン → runner上での RCE

脆弱なワークフロー（誰かが新しい issue を開いたときにトリガーされます）：
```yaml
name: New Issue Created
on:
issues:
types: [opened]
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: New issue
run: |
echo "New issue ${{ github.event.issue.title }} created"
- name: Add "new" label to issue
uses: actions-ecosystem/action-add-labels@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
labels: new
```
攻撃者が $(id) をタイトルにした issue を開くと、レンダリングされたステップは次のようになります:
```sh
echo "New issue $(id) created"
```
コマンド置換は runner 上で id を実行します。出力例:
```
New issue uid=1001(runner) gid=118(docker) groups=118(docker),4(adm),100(users),999(systemd-journal) created
```
なぜ引用はあなたを守れないのか:
- 式はまず展開され、その結果できたスクリプトが実行されます。信頼できない値に $(...), `;`, `"`/`'`, または改行が含まれていると、引用していてもプログラム構造を変更される可能性があります。

## 安全なパターン (shell variables via env)

Correct mitigation: copy untrusted input into an environment variable, then use native shell expansion ($VAR) in the run script. Do not re-embed with ${{ ... }} inside the command.
```yaml
# safe
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: New issue
env:
TITLE: ${{ github.event.issue.title }}
run: |
echo "New issue $TITLE created"
```
注意:
- Avoid using ${{ env.TITLE }} inside run:. That reintroduces template rendering back into the command and brings the same injection risk.
- Prefer passing untrusted inputs via env: mapping and reference them with $VAR in run:.

## 読者がトリガーできるサーフェス（未検証として扱う）

public repositories に対して読み取りのみの権限しか持たないアカウントでも、多くのイベントをトリガーできます。これらのイベントに由来するコンテキスト内の任意のフィールドは、反証されない限り攻撃者制御下にあると見なすべきです。例:
- issues, issue_comment
- discussion, discussion_comment (orgs can restrict discussions)
- pull_request, pull_request_review, pull_request_review_comment
- pull_request_target (dangerous if misused, runs in base repo context)
- fork (anyone can fork public repos)
- watch (starring a repo)
- Indirectly via workflow_run/workflow_call chains

どの特定のフィールドが攻撃者制御下にあるかはイベントごとに異なります。詳細は GitHub Security Lab の未検証入力に関するガイドを参照してください: https://securitylab.github.com/resources/github-actions-untrusted-input/

## 実用的なヒント

- Minimize use of expressions inside run:. Prefer env: mapping + $VAR.
- 入力を変換する必要がある場合は、シェル内で安全なツール（printf %q、jq -r 等）を使って行い、始点はシェル変数にしてください。
- ブランチ名、PR titles、ユーザー名、ラベル、ディスカッションタイトル、PR head refs をスクリプト、コマンドラインフラグ、またはファイルパスに挿入する際は特に慎重になってください。
- 再利用可能な workflows や composite actions に対しても同じパターンを適用してください: env にマップしてから $VAR を参照する。

## References

- [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1)
- [GitHub workflow syntax](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions)
- [Contexts and expression syntax](https://docs.github.com/en/actions/learn-github-actions/contexts)
- [Untrusted input reference for GitHub Actions](https://securitylab.github.com/resources/github-actions-untrusted-input/)

{{#include ../../../banners/hacktricks-training.md}}
