Translated ['', 'src/pentesting-ci-cd/github-security/abusing-github-act

This commit is contained in:
Translator
2026-07-06 15:30:40 +00:00
parent 8473cf6c5d
commit 448a654ef1
@@ -2,20 +2,20 @@
{{#include ../../../banners/hacktricks-training.md}}
## Verstaan die risiko
## Begrip van 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.
GitHub Actions render expressions ${{ ... }} voordat die step uitgevoer word. Die gerenderde waarde word in die step se program geplak (vir run steps, n shell script). As jy onbetroubare input direk binne run: interpoleer, beheer die aanvaller deel van die shell program en kan arbitrêre commands 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.
Sleutel punte:
- Rendering gebeur voor execution. Die run script word gegenereer met alle expressions opgelos, en dan deur die shell uitgevoer.
- Baie contexts bevat user-controlled fields, 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 quoting binne run: is nie n betroubare defense nie, omdat die injection op die template rendering stage plaasvind. Attacker's kan uit quotes breek of operators via gekunstelde input inject.
## Kwetsbare patroon → RCE on runner
## Kwesbare patroon → RCE op runner
Kwetsbare workflow (triggered when someone opens a new issue):
Kwesbare workflow (getrigger wanneer iemand n nuwe issue open):
```yaml
name: New Issue Created
on:
@@ -36,20 +36,56 @@ with:
github_token: ${{ secrets.GITHUB_TOKEN }}
labels: new
```
As 'n aanvaller 'n issue met die titel $(id) oopmaak, word die gerenderde stap:
As n attacker 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:
Die command substitution voer id op die runner uit. Voorbeeld-uitset:
```
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.
- Expressions word eerste gerender, dan hardloop die resulting script. As die untrusted value $(...), `;`, `"`/`'`, of newlines bevat, kan dit die programstruktuur verander ten spyte van jou quoting.
## Veilige patroon (shell variables via env)
## Comment-state confusion: gespoofde bot comments → shell injection
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.
n Gevaarlike variant verskyn wanneer n workflow **comments soek en later die teruggestuurde comment as trusted automation state behandel**. Byvoorbeeld, `peter-evans/find-comment` kan soek volgens `body-includes` en die ooreenstemmende `comment-body` as n step output blootstel. As die workflow **nie** ook `comment-author` beperk nie, kan enige user wat kan comment die marker text spoof wat van n bot verwag word.
```yaml
- uses: peter-evans/find-comment@v4
id: fc
with:
issue-number: ${{ github.event.issue.number }}
body-includes: "Opened a new issue in org/repo:"
```
As daardie uitvoer later in shell-sintaksis ingebed word, word die workflow uitbuitbaar, selfs al was die oorspronklike bron "net 'n comment":
```yaml
- run: |
if [ '${{ steps.fc.outputs.comment-body }}' = '' ]; then
echo "new issue needed"
fi
```
n Aanvaller kan n comment plaas wat beide:
- die gesoekte marker string pas, en
- shell-breaking content bevat soos `' ]; <cmd>; if [ 'x`
Nadat GitHub `${{ ... }}` render, ontvang Bash attacker-beheerde syntax, nie data nie. Dit skep n **two-stage exploit**:
1. **Provenance confusion**: die workflow verwar attacker comments met bot state.
2. **Script injection**: die teruggestuurde `comment-body` word in `run:` geplak en uitgevoer.
### TOCTOU race against bot comments
As die wettige bot comment eers geskep word ná n vroeër stap, kan n aanvaller dit race deur die gespoofde comment eerste te plaas. As die search action die aanvaller se comment terugstuur voordat die regte bot comment bestaan (of voordat dit gekies word), kan n public commenter met lae privileges n `issue_comment`/issue workflow in privileged runner execution verander.
### Safer patterns for comment-driven automation
- Wanneer jy `find-comment` gebruik, vereis **beide content en provenance** (`comment-author`, repository/App identity, of n ander sterk binding).
- Moenie comments as state gebruik as n label, artifact, issue field, of external datastore dieselfde state veiliger kan hou nie.
- Moet nooit `comment-body`, issue titles, labels, of enige workflow output wat daarvan afgelei is direk in `run:` plak nie.
- As jy comment text móét verwerk, stuur dit deur `env:` of n file en hanteer dit slegs as data.
## Safe pattern (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:
@@ -63,31 +99,39 @@ 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:.
- Vermy die gebruik van ${{ env.TITLE }} binne run:. Dit bring template rendering terug in die command en bring dieselfde injection risk.
- Verkies om untrusted inputs via env: mapping deur te gee en verwys daarna met $VAR in run:.
## Leser-aktiveerbare oppervlaktes (behandel as onbetroubaar)
## Reader-triggerable surfaces (treat as untrusted)
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:
Accounts met slegs read permission op public repositories kan steeds baie events trigger. Enige field in contexts wat van hierdie events afgelei is, moet as attacker-controlled beskou word tensy anders bewys. Voorbeelde:
- issues, issue_comment
- discussion, discussion_comment (orgs can restrict discussions)
- discussion, discussion_comment (orgs kan discussions beperk)
- 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)
- pull_request_target (dangerous as dit misbruik word, runs in base repo context)
- fork (enigiemand kan public repos fork)
- watch (starring a repo)
- Indirek via workflow_run/workflow_call chains
- Indirectly via workflow_run/workflow_call chains
Watter spesifieke velde deur 'n aanvaller beheer word, is event-spesifiek. Raadpleeg GitHub Security Labs untrusted input guide: https://securitylab.github.com/resources/github-actions-untrusted-input/
Watter spesifieke fields attacker-controlled is, is event-specific. Raadpleeg GitHub Security Lab se untrusted input guide: https://securitylab.github.com/resources/github-actions-untrusted-input/
## Praktiese wenke
## Local validation without touching the target repo
- 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.
Jy kan baie GitHub Actions script injections veilig reproduseer met [`act`](https://github.com/nektos/act): genereer 'n synthetic event JSON, run die vulnerable workflow locally, en vervang die external action output met 'n controlled value (byvoorbeeld 'n mocked `comment-body`). Dit is nuttig om payload structure te debug, te verifieer of die injected text nog geldige Bash syntax laat, en harmless canary exfiltration te bevestig voor enige live test.
## Practical tips
- Minimaliseer gebruik van expressions binne run:. Verkies env: mapping + $VAR.
- As jy input moet transformeer, doen dit in die shell met safe tools (printf %q, jq -r, ens.), maar steeds vanaf 'n shell variable.
- Wees ekstra versigtig wanneer branch names, PR titles, usernames, labels, discussion titles, en PR head refs in scripts, command-line flags, of file paths geïnkorporeer word.
- Vir reusable workflows en composite actions, pas dieselfde patroon toe: map na env en verwys dan $VAR.
## References
- [Find Comment, Get Shell: Command Injection in dbts GitHub Actions](https://landh.tech/blog/20260701-find-comment-get-shell)
- [peter-evans/find-comment](https://github.com/peter-evans/find-comment)
- [GHSL-2023-109: GitHub Actions command injection in a TDesign Vue Next workflow](https://securitylab.github.com/advisories/GHSL-2023-109_TDesign_Vue_Next/)
- [nektos/act](https://github.com/nektos/act)
- [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)