From ad70b50bb0c24711076f66c91cea8737b72a91b0 Mon Sep 17 00:00:00 2001 From: Translator Date: Mon, 6 Jul 2026 15:30:35 +0000 Subject: [PATCH] Translated ['', 'src/pentesting-ci-cd/github-security/abusing-github-act --- .../gh-actions-context-script-injections.md | 104 +++++++++++++----- 1 file changed, 74 insertions(+), 30 deletions(-) diff --git a/src/pentesting-ci-cd/github-security/abusing-github-actions/gh-actions-context-script-injections.md b/src/pentesting-ci-cd/github-security/abusing-github-actions/gh-actions-context-script-injections.md index bd4e8ae5f..c429bc3bc 100644 --- a/src/pentesting-ci-cd/github-security/abusing-github-actions/gh-actions-context-script-injections.md +++ b/src/pentesting-ci-cd/github-security/abusing-github-actions/gh-actions-context-script-injections.md @@ -4,18 +4,18 @@ ## Kuelewa hatari -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. +GitHub Actions hu-render expressions ${{ ... }} kabla step haitekelezwi. Thamani iliyo-rendered huwekwa ndani ya programu ya step hiyo (kwa run steps, shell script). Ukichomeka input isiyoaminika moja kwa moja ndani ya run:, attacker hudhibiti sehemu ya shell program na anaweza kuexecute 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 -Vidokezo muhimu: -- Uundaji (rendering) hufanyika kabla ya utekelezaji. The run script inaundwa kwa expressions zote zilizosuluhishwa, kisha inatekelezwa na shell. -- Contexts nyingi zina nyanja zinazodhibitiwa na mtumiaji kulingana na tukio linalochochea (issues, PRs, comments, discussions, forks, stars, n.k.). Angalia rejea ya untrusted input: https://securitylab.github.com/resources/github-actions-untrusted-input/ -- Shell quoting ndani ya run: sio ulinzi wa kuaminika, kwa sababu injection hutokea katika hatua ya template rendering. Wavamizi wanaweza kuvunja nukuu au kuingiza operators kupitia input iliyotengenezwa kwa ustadi. +Mambo muhimu: +- Rendering hutokea kabla ya execution. run script hutengenezwa na expressions zote zikiwa zimeshatatuliwa, kisha shell huiexecute. +- Contexts nyingi zina fields zinazodhibitiwa na user kutegemea event inayochochea (issues, PRs, comments, discussions, forks, stars, etc.). Tazama untrusted input reference: https://securitylab.github.com/resources/github-actions-untrusted-input/ +- Shell quoting ndani ya run: si ulinzi wa kuaminika, kwa sababu injection hutokea katika hatua ya template rendering. Attackers wanaweza kutoka nje ya quotes au kuinject operators kupitia input iliyotengenezwa kwa hila. -## Mfano hatarishi → RCE on runner +## Vulnerable pattern → RCE on runner -Workflow hatarishi (inayoanzishwa wakati mtu anafungua issue mpya): +Vulnerable workflow (triggered when someone opens a new issue): ```yaml name: New Issue Created on: @@ -36,20 +36,56 @@ with: github_token: ${{ secrets.GITHUB_TOKEN }} labels: new ``` -Ikiwa mshambuliaji anafungua issue yenye kichwa $(id), hatua iliyowasilishwa itakuwa: +Kama mshambuliaji akifungua issue yenye kichwa $(id), hatua iliyotolewa inakuwa: ```sh echo "New issue $(id) created" ``` -Ubadilishaji wa amri (command substitution) unaendesha id kwenye runner. Mfano wa pato: +Ubadilishaji wa amri huendesha id kwenye runner. Mfano wa output: ``` New issue uid=1001(runner) gid=118(docker) groups=118(docker),4(adm),100(users),999(systemd-journal) created ``` -Kwa nini kunukuu hakukuokoa: -- Mielezo zinatengenezwa kwanza, kisha script inayotokana inaendeshwa. Ikiwa thamani isiyoaminika ina $(...), `;`, `"`/`'`, au newlines, inaweza kubadilisha muundo wa programu licha ya kunukuu kwako. +Kwa nini quoting hakukuokoi: +- Expressions hutolewa kwanza, kisha script inayotokana nayo huendeshwa. Ikiwa thamani isiyoaminika ina $(...), `;`, `"`/`'`, au newlines, inaweza kubadilisha muundo wa program licha ya quoting yako. -## Mfano salama (shell variables via env) +## Comment-state confusion: spoofed bot comments → shell injection -Kupunguza hatari sahihi: nakili ingizo lisiloaminika ndani ya environment variable, kisha tumia native shell expansion ($VAR) katika run script. Usirudishe tena kwa ${{ ... }} ndani ya command. +Toleo hatari linaonekana wakati workflow **inatafuta comments kisha baadaye hutumia comment iliyorejeshwa kama trusted automation state**. Kwa mfano, `peter-evans/find-comment` inaweza kutafuta kwa `body-includes` na kuonyesha `comment-body` inayolingana kama step output. Ikiwa workflow haizuii pia `comment-author`, mtumiaji yeyote anayeweza kutoa comment anaweza spoof text ya marker inayotarajiwa kutoka kwa bot. +```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:" +``` +Ikiwa output hiyo baadaye itaingizwa ndani ya shell syntax, workflow inakuwa exploitable hata kama chanzo cha asili kilikuwa “just a comment”: +```yaml +- run: | +if [ '${{ steps.fc.outputs.comment-body }}' = '' ]; then +echo "new issue needed" +fi +``` +Mshambulizi anaweza kuchapisha comment ambayo yote: +- inalingana na searched marker string, na +- ina shell-breaking content kama `' ]; ; if [ 'x` + +Baada ya GitHub kutoa `${{ ... }}`, Bash inapokea syntax inayodhibitiwa na mshambulizi, si data. Hii hutengeneza **two-stage exploit**: +1. **Provenance confusion**: workflow huchanganya comments za mshambulizi na bot state. +2. **Script injection**: `comment-body` iliyorejeshwa hubandikwa ndani ya `run:` na kutekelezwa. + +### TOCTOU race dhidi ya bot comments + +Kama legitimate bot comment huundwa tu baada ya hatua ya awali, mshambulizi anaweza kukimbizana nayo kwa kuchapisha spoofed comment kwanza. Ikiwa search action inarejesha comment ya mshambulizi kabla ya real bot comment kuwepo (au kabla haijachaguliwa), low-privilege public commenter anaweza kubadilisha workflow ya `issue_comment`/issue kuwa privileged runner execution. + +### Safer patterns for comment-driven automation + +- Unapotumia `find-comment`, hitaji **content na provenance** zote mbili (`comment-author`, repository/App identity, au strong binding nyingine). +- Usitumie comments kama state ikiwa label, artifact, issue field, au external datastore vinaweza kuhifadhi state hiyo hiyo kwa usalama zaidi. +- Kamwe usibandike `comment-body`, issue titles, labels, au workflow output yoyote inayotokana nazo moja kwa moja ndani ya `run:`. +- Ikiwa ni lazima kutumia comment text, ipitishe kupitia `env:` au file na ishughulikie kama data tu. + +## Safe pattern (shell variables via env) + +Correct mitigation: nakili untrusted input ndani ya environment variable, kisha tumia native shell expansion ($VAR) kwenye run script. Usiiingize tena kwa kutumia ${{ ... }} ndani ya command. ```yaml # safe jobs: @@ -62,32 +98,40 @@ TITLE: ${{ github.event.issue.title }} run: | echo "New issue $TITLE created" ``` -Vidokezo: -- Epukana kutumia ${{ env.TITLE }} ndani ya run:. Hii inarejesha template rendering ndani ya amri na inaleta hatari ile ile ya injection. -- Pendelea kupitisha inputs zisizo waaminifu kupitia env: mapping na kuzi-refer kwa $VAR ndani ya run:. +Notes: +- Epuka kutumia ${{ env.TITLE }} ndani ya run:. Hilo linaanzisha tena template rendering ndani ya command na kuleta hatari ileile ya injection. +- Pendelea kupitisha inputs zisizoaminika kupitia env: mapping na uzirejelee kwa $VAR ndani ya run:. -## Nyuso zinazoweza kusababishwa na msomaji (zitachukuliwe kuwa zisizo waaminifu) +## Reader-triggerable surfaces (chukulia kama zisizoaminika) -Akaunti zenye tu ruhusa ya kusoma kwenye public repositories bado zinaweza kusababisha matukio mengi. Kila uwanja katika contexts zinazotokana na matukio haya lazima uchukuliwe kuwa udhibitiwa na mshambuliaji isipokuwa kuthibitishwa vinginevyo. Mifano: +Accounts zenye only read permission kwenye public repositories bado zinaweza ku-trigger events nyingi. Kila field ndani ya contexts zinazotokana na events hizi lazima ichukuliwe kama attacker-controlled isipokuwa ithibitishwe vinginevyo. Mifano: - issues, issue_comment -- discussion, discussion_comment (orgs zinaweza kuzuia mijadala) +- discussion, discussion_comment (orgs zinaweza kuzuia discussions) - pull_request, pull_request_review, pull_request_review_comment -- pull_request_target (hatari ikiwa itatumika vibaya, inaendesha katika muktadha wa base repo) -- fork (mtu yeyote anaweza kufanya fork ya repos public) -- watch (kuweka nyota kwenye repo) -- Kwa njia isiyo ya moja kwa moja kupitia mnyororo wa workflow_run/workflow_call +- pull_request_target (hatari ikitumiwa vibaya, hu-run katika base repo context) +- fork (mtu yeyote anaweza kufanya fork ya public repos) +- watch (starring a repo) +- Indirectly via workflow_run/workflow_call chains -Ni kutegemea tukio ni uwanja gani hasa unaodhibitiwa na mshambuliaji. Rejea GitHub Security Lab’s untrusted input guide: https://securitylab.github.com/resources/github-actions-untrusted-input/ +Ni fields gani hasa zinadhibitiwa na attacker hutegemea event husika. Rejea GitHub Security Lab’s untrusted input guide: https://securitylab.github.com/resources/github-actions-untrusted-input/ -## Vidokezo vya vitendo +## Local validation bila kugusa target repo -- Punguza matumizi ya expressions ndani ya run:. Tumia env: mapping + $VAR. -- Ikiwa lazima ubadilishe input, fanya hivyo kwenye shell ukitumia zana salama (printf %q, jq -r, n.k.), ukianza bado kutoka kwa shell variable. -- Kuwa wa tahadhari zaidi unapoingiza branch names, PR titles, usernames, labels, discussion titles, na PR head refs ndani ya scripts, command-line flags, au file paths. -- Kwa reusable workflows na composite actions, tumia mtindo ule ule: map kwenda env kisha urejeee kwa $VAR. +Unaweza kurudisha kwa usalama script injections nyingi za GitHub Actions kwa kutumia [`act`](https://github.com/nektos/act): tengeneza synthetic event JSON, run workflow iliyo vulnerable locally, na badilisha output ya external action na value unaodhibitiwa (kwa mfano mocked `comment-body`). Hii ni muhimu kwa ku-debug payload structure, kuthibitisha kama text iliyoinjected bado inaacha valid Bash syntax, na kuthibitisha harmless canary exfiltration kabla ya live test yoyote. -## Marejeo +## Practical tips +- Punguza matumizi ya expressions ndani ya run:. Pendelea env: mapping + $VAR. +- Iwapo lazima ubadilishe input, ifanye kwenye shell kwa kutumia safe tools (printf %q, jq -r, etc.), ukianza bado kutoka kwenye shell variable. +- Kuwa makini zaidi unapohusisha branch names, PR titles, usernames, labels, discussion titles, na PR head refs ndani ya scripts, command-line flags, au file paths. +- Kwa reusable workflows na composite actions, tumia pattern ileile: map to env kisha rejelea $VAR. + +## References + +- [Find Comment, Get Shell: Command Injection in dbt’s 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)