Gh Actions - Context Script Injections
Tip
Apprenez & pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Soutenez HackTricks
- Consultez les subscription plans!
- Rejoignez le đŹ Discord group ou le telegram group ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des hacking tricks en soumettant des PRs aux HackTricks et HackTricks Cloud github repos.
Comprendre le risque
GitHub Actions Ă©value les expressions ${{ ⊠}} avant que lâĂ©tape nâexĂ©cute. La valeur Ă©valuĂ©e est insĂ©rĂ©e dans le programme de lâĂ©tape (pour les Ă©tapes run, un script shell). Si vous interpolez des entrĂ©es non fiables directement dans run:, lâattaquant contrĂŽle une partie du script shell et peut exĂ©cuter des commandes arbitraires.
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
Points clés :
- LâĂ©valuation a lieu avant lâexĂ©cution. Le script run est gĂ©nĂ©rĂ© avec toutes les expressions rĂ©solues, puis exĂ©cutĂ© par le shell.
- De nombreux contexts contiennent des champs contrĂŽlĂ©s par lâutilisateur selon lâĂ©vĂ©nement dĂ©clencheur (issues, PRs, comments, discussions, forks, stars, etc.). Voir la rĂ©fĂ©rence sur les entrĂ©es non fiables : https://securitylab.github.com/resources/github-actions-untrusted-input/
- Le quoting du shell Ă lâintĂ©rieur de run: nâest pas une dĂ©fense fiable, car lâinjection se produit lors de lâĂ©tape de rendu du template. Les attaquants peuvent sortir des guillemets ou injecter des opĂ©rateurs via des entrĂ©es spĂ©cialement conçues.
ModĂšle vulnĂ©rable â RCE on runner
Workflow vulnĂ©rable (dĂ©clenchĂ© lorsquâune personne ouvre une nouvelle issue):
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
Si un attaquant ouvre un issue avec le titre $(id), lâĂ©tape rendue devient :
echo "New issue $(id) created"
La substitution de commande exécute id sur le runner. Exemple de sortie :
New issue uid=1001(runner) gid=118(docker) groups=118(docker),4(adm),100(users),999(systemd-journal) created
Pourquoi les guillemets ne suffisent pas :
- Les expressions sont Ă©valuĂ©es en premier, puis le script rĂ©sultant sâexĂ©cute. Si la valeur non fiable contient $(âŠ),
;,"/', ou des retours à la ligne, elle peut modifier la structure du programme malgré vos guillemets.
ModÚle sûr (shell variables via env)
Mitigation correcte : copiez lâentrĂ©e non fiable dans une variable dâenvironnement, puis utilisez lâexpansion native du shell ($VAR) dans le script dâexĂ©cution. Ne la rĂ©injectez pas avec ${{ ⊠}} dans la commande.
# safe
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: New issue
env:
TITLE: ${{ github.event.issue.title }}
run: |
echo "New issue $TITLE created"
Remarques:
- Ăvitez dâutiliser ${{ env.TITLE }} dans run:. Cela rĂ©introduit le rendu du template dans la commande et entraĂźne le mĂȘme risque dâinjection.
- PrivilĂ©giez le passage dâentrĂ©es non fiables via le mapping env: et rĂ©fĂ©rencez-les avec $VAR dans run:.
Surfaces déclenchables par un lecteur (à traiter comme non fiables)
Les comptes avec seulement la permission de lecture sur les dĂ©pĂŽts publics peuvent quand mĂȘme dĂ©clencher de nombreux Ă©vĂ©nements. Tout champ des contextes dĂ©rivĂ©s de ces Ă©vĂ©nements doit ĂȘtre considĂ©rĂ© comme contrĂŽlĂ© par un attaquant sauf preuve du contraire. Exemples:
- issues, issue_comment
- discussion, discussion_comment (les organisations peuvent restreindre les discussions)
- pull_request, pull_request_review, pull_request_review_comment
- pull_request_target (dangereux sâil est mal utilisĂ©, sâexĂ©cute dans le contexte du dĂ©pĂŽt de base)
- fork (nâimporte qui peut forker des dĂ©pĂŽts publics)
- watch (le fait dâajouter une Ă©toile Ă un dĂ©pĂŽt)
- Indirectement via des chaĂźnes workflow_run/workflow_call
Les champs spĂ©cifiques contrĂŽlĂ©s par un attaquant dĂ©pendent de lâĂ©vĂ©nement. Consultez le guide de GitHub Security Lab sur les entrĂ©es non fiables : https://securitylab.github.com/resources/github-actions-untrusted-input/
Conseils pratiques
- Minimisez lâutilisation dâexpressions dans run:. PrivilĂ©giez le mapping env: + $VAR.
- Si vous devez transformer une entrĂ©e, faites-le dans le shell en utilisant des outils sĂ»rs (printf %q, jq -r, etc.), en partant toujours dâune variable shell.
- Soyez particuliĂšrement prudent lors de lâinterpolation de branch names, PR titles, usernames, labels, discussion titles et PR head refs dans des scripts, des options en ligne de commande ou des chemins de fichiers.
- Pour les reusable workflows et composite actions, appliquez le mĂȘme schĂ©ma : mappez vers env puis rĂ©fĂ©rencez $VAR.
Références
- GitHub Actions: A Cloudy Day for Security - Part 1
- GitHub workflow syntax
- Contexts and expression syntax
- Untrusted input reference for GitHub Actions
Tip
Apprenez & pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Soutenez HackTricks
- Consultez les subscription plans!
- Rejoignez le đŹ Discord group ou le telegram group ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des hacking tricks en soumettant des PRs aux HackTricks et HackTricks Cloud github repos.
HackTricks Cloud

