Gh Actions - Context Script Injections
Tip
AWS Hacking’i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın:HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın:HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- Abonelik planlarını kontrol edin!
- Katılın 💬 Discord group veya telegram group veya Twitter’da bizi takip edin 🐦 @hacktricks_live.
- PR göndererek hacking tricks paylaşın: HackTricks ve HackTricks Cloud github repos.
Riskin anlaşılması
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
Önemli noktalar:
- Render işlemi yürütmeden önce gerçekleşir. Tüm ifadeler çözümlendikten sonra run script oluşturulur ve sonra shell tarafından çalıştırılır.
- Birçok contexts kullanıcı-kontrollü alanlar içerir; bu, tetikleyici olaya bağlıdır (issues, PRs, comments, discussions, forks, stars, vb.). Güvenilmeyen input referansına bakın: https://securitylab.github.com/resources/github-actions-untrusted-input/
- run: içindeki shell quoting güvenilir bir savunma değildir, çünkü enjeksiyon şablon render aşamasında gerçekleşir. Saldırganlar tırnaklardan çıkabilir veya özel olarak hazırlanmış girdilerle operatörler enjekte edebilir.
Zayıf örüntü → RCE on runner
Zayıf workflow (birisi yeni bir issue açtığında tetiklenir):
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
Eğer bir saldırgan $(id) başlıklı bir issue açarsa, renderlenen adım şöyle olur:
echo "New issue $(id) created"
Komut değişimi runner üzerinde id komutunu çalıştırır. Örnek çıktı:
New issue uid=1001(runner) gid=118(docker) groups=118(docker),4(adm),100(users),999(systemd-journal) created
Neden tırnaklama sizi kurtarmaz:
- İfadeler önce render edilir, sonra ortaya çıkan script çalıştırılır. Eğer güvensiz değer $(…),
;,"/', veya yeni satırlar içeriyorsa, tırnaklama yapmış olsanız bile program yapısını değiştirebilir.
Güvenli desen (shell variables via env)
Doğru önlem: güvensiz girdiyi bir environment variable’a kopyalayın, sonra run script içinde native shell expansion ($VAR) kullanın. Komutun içinde ${{ … }} ile tekrar gömmeyin.
# safe
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: New issue
env:
TITLE: ${{ github.event.issue.title }}
run: |
echo "New issue $TITLE created"
Notlar:
- run: içinde ${{ env.TITLE }} kullanmaktan kaçının. Bu, şablon render’ını komutun içine yeniden sokar ve aynı enjeksiyon riskini getirir.
- Güvensiz girdileri env: mapping ile geçirmek ve run: içinde bunlara $VAR ile referans vermek tercih edin.
Reader-triggerable surfaces (treat as untrusted)
Sadece public repository’lerde okuma izni olan hesaplar bile birçok eventi tetikleyebilir. Bu olaylardan türetilen contexts içindeki herhangi bir alan, aksi kanıtlanana kadar saldırgan kontrolünde kabul edilmelidir. Örnekler:
- issues, issue_comment
- discussion, discussion_comment (org’lar discussions’ı kısıtlayabilir)
- pull_request, pull_request_review, pull_request_review_comment
- pull_request_target (kötü kullanılırsa tehlikeli, base repo context’inde çalışır)
- fork (herkes public repo’yu fork’layabilir)
- watch (bir repo’yu star’lamak)
- Dolaylı olarak workflow_run/workflow_call zincirleri vasıtasıyla
Hangi spesifik alanların saldırgan kontrolünde olduğu olay bazlıdır. GitHub Security Lab’in untrusted input rehberine bakın: https://securitylab.github.com/resources/github-actions-untrusted-input/
Practical tips
- run: içinde expressions kullanımını en aza indirin. env: mapping + $VAR tercih edin.
- Eğer girdiyi dönüştürmeniz gerekiyorsa, bunu shell içinde güvenli araçlarla yapın (printf %q, jq -r, vb.), yine bir shell değişkeninden başlayarak.
- Branch isimlerini, PR başlıklarını, kullanıcı adlarını, label’ları, discussion başlıklarını ve PR head ref’lerini script’lere, komut satırı flag’lerine veya dosya yollarına interpolasyon yaparken ekstra dikkatli olun.
- Reusable workflows ve composite actions için de aynı deseni uygulayın: env’e map edip sonra $VAR ile referanslayın.
References
- GitHub Actions: A Cloudy Day for Security - Part 1
- GitHub workflow syntax
- Contexts and expression syntax
- Untrusted input reference for GitHub Actions
Tip
AWS Hacking’i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın:HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın:HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- Abonelik planlarını kontrol edin!
- Katılın 💬 Discord group veya telegram group veya Twitter’da bizi takip edin 🐦 @hacktricks_live.
- PR göndererek hacking tricks paylaşın: HackTricks ve HackTricks Cloud github repos.
HackTricks Cloud

