# Gh Actions - Context Script Injections

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

## Verstaan die risiko

GitHub Actions verwerk uitdrukkings ${{ ... }} voordat die stap uitgevoer word. Die verwerkte waarde word in die stap se program geplak (vir run steps, a shell script). As jy onbetroubare inset direk binne run: interpoleer, beheer die aanvaller 'n deel van die shell-program en kan arbitrêre opdragte uitvoer.

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

Belangrike punte:
- Renderering vind plaas voordat uitvoering begin. Die run script word gegenereer met alle uitdrukkings opgelos, en dan deur die shell uitgevoer.
- Baie contexts bevat deur gebruikers beheerde velde, afhangend van die triggering event (issues, PRs, comments, discussions, forks, stars, ens.). Sien die untrusted input reference: https://securitylab.github.com/resources/github-actions-untrusted-input/
- Shell-kwoting binne run: is nie 'n betroubare verdediging nie, omdat die injectie op die template-rendering stadium plaasvind. Aanvallers kan uit aanhalingstekens breek of operatoren injekteer via gekruide insette.

## Kwetsbare patroon → RCE on runner

Kwetsbare 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
```
As 'n aanvaller 'n issue met die titel $(id) oopmaak, word die gerenderde stap:
```sh
echo "New issue $(id) created"
```
Die command substitution voer id op die runner uit. Voorbeelduitset:
```
New issue uid=1001(runner) gid=118(docker) groups=118(docker),4(adm),100(users),999(systemd-journal) created
```
Waarom quoting jou nie red nie:
- Expressions word eers gerender, en dan word die resulterende script uitgevoer. As die onbetroubare waarde $(...), `;`, `"`/`'`, of newlines bevat, kan dit die programstruktuur verander ten spyte van jou quoting.

## Veilige patroon (shell variables via env)

Korrekte teenmaatreël: kopieer die onbetroubare inset na 'n omgewingvariabele, en gebruik dan die native shell-uitbreiding ($VAR) in die run-skrip. Moet nie ${{ ... }} weer inbed binne die opdrag nie.
```yaml
# safe
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: New issue
env:
TITLE: ${{ github.event.issue.title }}
run: |
echo "New issue $TITLE created"
```
Notes:
- 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:.

## Leser-aktiveerbare oppervlaktes (behandel as onbetroubaar)

Rekeninge met slegs leesreg op openbare repositories kan steeds baie events uitlok. Enige veld in contexts afgelei van hierdie events moet as deur 'n aanvaller beheer beskou word tensy teendeel bewys is. Voorbeelde:
- issues, issue_comment
- discussion, discussion_comment (orgs can restrict discussions)
- pull_request, pull_request_review, pull_request_review_comment
- pull_request_target (gevaarlik as dit misbruik word, runs in base repo context)
- fork (anyone can fork public repos)
- watch (starring a repo)
- Indirek via workflow_run/workflow_call chains

Watter spesifieke velde deur 'n aanvaller beheer word, is event-spesifiek. Raadpleeg GitHub Security Lab’s untrusted input guide: https://securitylab.github.com/resources/github-actions-untrusted-input/

## Praktiese wenke

- Minimaliseer die gebruik van expressions binne run:. Gee voorkeur aan env: mapping + $VAR.
- As jy insette moet transformeer, doen dit in die shell met veilige gereedskap (printf %q, jq -r, etc.), steeds beginnende vanaf 'n shell variable.
- Wees ekstra versigtig wanneer jy branch names, PR titles, usernames, labels, discussion titles, en PR head refs in interpolasie in scripts, command-line flags, of file paths plaas.
- Vir reusable workflows en composite actions, pas dieselfde patroon toe: map na env dan verwys met $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}}
