Gh Actions - Context Script Injections

Reading time: 5 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks

Розуміння ризику

GitHub Actions renders expressions ${{ ... }} before the step executes. The rendered value is pasted into the step’s program (for run steps, a shell script). If you interpolate untrusted input directly inside run:, the attacker controls part of the shell program and can execute arbitrary commands.

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

Ключові моменти:

  • Rendering happens before execution. The run script is generated with all expressions resolved, then executed by the shell.
  • Many contexts contain user-controlled fields depending on the triggering event (issues, PRs, comments, discussions, forks, stars, etc.). Див. untrusted input reference: https://securitylab.github.com/resources/github-actions-untrusted-input/
  • Shell quoting inside run: is not a reliable defense, because the injection occurs at the template rendering stage. Attackers can break out of quotes or inject operators via crafted input.

Уразливий шаблон → RCE on runner

Вразливий workflow (triggered when someone opens a new 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

Якщо зловмисник відкриє issue з назвою $(id), відрендерений крок стане:

sh
echo "New issue $(id) created"

Підстановка команди виконує id на runner. Приклад виводу:

New issue uid=1001(runner) gid=118(docker) groups=118(docker),4(adm),100(users),999(systemd-journal) created

Чому лапки не рятують:

  • Вираження обчислюються спочатку, а потім виконується отриманий скрипт. Якщо ненадійне значення містить $(...), ;, "/' або нові рядки, воно може змінити структуру програми незважаючи на ваші лапки.

Безпечний шаблон (shell variables via env)

Правильне пом'якшення: скопіюйте ненадійне вхідне значення у змінну середовища, потім використовуйте нативне shell-розгортання ($VAR) у run script. Не вбудовуйте знову ${{ ... }} всередині команди.

yaml
# safe
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: New issue
env:
TITLE: ${{ github.event.issue.title }}
run: |
echo "New issue $TITLE created"

Примітки:

  • Уникайте використання ${{ env.TITLE }} всередині run:. Це знову вводить рендеринг шаблонів у команду і створює той самий ризик ін'єкції.
  • Краще передавати недовірені введення через відображення env: і звертатися до них як $VAR у run:.

Поверхні, які може ініціювати читач (вважати ненадійними)

Облікові записи з правом лише на читання у публічних репозиторіях все ще можуть викликати багато подій. Будь-яке поле в контекстах, отриманих із цих подій, слід вважати контрольованим зловмисником, якщо не доведено протилежне. Приклади:

  • 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’s untrusted input guide: https://securitylab.github.com/resources/github-actions-untrusted-input/

Практичні поради

  • Мінімізуйте використання виразів всередині run:. Віддавайте перевагу відображенню env: + $VAR.
  • Якщо потрібно трансформувати введення, робіть це в shell, використовуючи безпечні інструменти (printf %q, jq -r, тощо), все одно починаючи з shell-змінної.
  • Будьте особливо обережні при інтерполяції імен гілок, заголовків PR, імен користувачів, labels, discussion titles та PR head refs у скрипти, параметри командного рядка або шляхи до файлів.
  • Для reusable workflows і composite actions застосовуйте той самий підхід: відобразіть у env, а потім посилайтеся на $VAR.

Посилання

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks