Skip to content

Commit 0d31686

Browse files
author
HackTricks News Bot
committed
Add content from: Find Comment, Get Shell: Command Injection in dbt’s GitHub A...
1 parent 36c997b commit 0d31686

2 files changed

Lines changed: 50 additions & 1 deletion

File tree

src/pentesting-ci-cd/github-security/abusing-github-actions/gh-actions-context-script-injections.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,46 @@ New issue uid=1001(runner) gid=118(docker) groups=118(docker),4(adm),100(users),
5353
Why quoting doesn’t save you:
5454
- Expressions are rendered first, then the resulting script runs. If the untrusted value contains $(...), `;`, `"`/`'`, or newlines, it can alter the program structure despite your quoting.
5555

56+
## Comment-state confusion: spoofed bot comments → shell injection
57+
58+
A dangerous variant appears when a workflow **searches comments and later treats the returned comment as trusted automation state**. For example, `peter-evans/find-comment` can search by `body-includes` and expose the matching `comment-body` as a step output. If the workflow does **not** also restrict `comment-author`, any user who can comment may spoof the marker text expected from a bot.
59+
60+
```yaml
61+
- uses: peter-evans/find-comment@v4
62+
id: fc
63+
with:
64+
issue-number: ${{ github.event.issue.number }}
65+
body-includes: "Opened a new issue in org/repo:"
66+
```
67+
68+
If that output is later embedded into shell syntax, the workflow becomes exploitable even though the original source was "just a comment":
69+
70+
```yaml
71+
- run: |
72+
if [ '${{ steps.fc.outputs.comment-body }}' = '' ]; then
73+
echo "new issue needed"
74+
fi
75+
```
76+
77+
An attacker can post a comment that both:
78+
- matches the searched marker string, and
79+
- contains shell-breaking content such as `' ]; <cmd>; if [ 'x`
80+
81+
After GitHub renders `${{ ... }}`, Bash receives attacker-controlled syntax, not data. This creates a **two-stage exploit**:
82+
1. **Provenance confusion**: the workflow mistakes attacker comments for bot state.
83+
2. **Script injection**: the returned `comment-body` is pasted into `run:` and executed.
84+
85+
### TOCTOU race against bot comments
86+
87+
If the legitimate bot comment is created only after some earlier step, an attacker may race it by posting the spoofed comment first. If the search action returns the attacker's comment before the real bot comment exists (or before it is selected), a low-privilege public commenter can turn an `issue_comment`/issue workflow into privileged runner execution.
88+
89+
### Safer patterns for comment-driven automation
90+
91+
- When using `find-comment`, require **both content and provenance** (`comment-author`, repository/App identity, or another strong binding).
92+
- Do not use comments as state if a label, artifact, issue field, or external datastore can hold the same state more safely.
93+
- Never paste `comment-body`, issue titles, labels, or any workflow output derived from them directly into `run:`.
94+
- If you must consume comment text, pass it through `env:` or a file and handle it as data only.
95+
5696
## Safe pattern (shell variables via env)
5797

5898
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.
@@ -87,6 +127,10 @@ Accounts with only read permission on public repositories can still trigger many
87127

88128
Which specific fields are attacker-controlled is event-specific. Consult GitHub Security Lab’s untrusted input guide: https://securitylab.github.com/resources/github-actions-untrusted-input/
89129

130+
## Local validation without touching the target repo
131+
132+
You can reproduce many GitHub Actions script injections safely with [`act`](https://github.com/nektos/act): generate a synthetic event JSON, run the vulnerable workflow locally, and replace the external action output with a controlled value (for example a mocked `comment-body`). This is useful to debug payload structure, verify whether the injected text still leaves valid Bash syntax, and confirm harmless canary exfiltration before any live test.
133+
90134
## Practical tips
91135

92136
- Minimize use of expressions inside run:. Prefer env: mapping + $VAR.
@@ -96,6 +140,10 @@ Which specific fields are attacker-controlled is event-specific. Consult GitHub
96140

97141
## References
98142

143+
- [Find Comment, Get Shell: Command Injection in dbt’s GitHub Actions](https://landh.tech/blog/20260701-find-comment-get-shell)
144+
- [peter-evans/find-comment](https://github.com/peter-evans/find-comment)
145+
- [GHSL-2023-109: GitHub Actions command injection in a TDesign Vue Next workflow](https://securitylab.github.com/advisories/GHSL-2023-109_TDesign_Vue_Next/)
146+
- [nektos/act](https://github.com/nektos/act)
99147
- [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1)
100148
- [GitHub workflow syntax](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions)
101149
- [Contexts and expression syntax](https://docs.github.com/en/actions/learn-github-actions/contexts)

src/pentesting-cloud/azure-security/az-privilege-escalation/az-automation-accounts-privesc.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ sudo nc -nlvp 443
314314

315315
The scheduled task executes the payload, achieving SYSTEM-level privileges.
316316

317-
{{#include ../../../banners/hacktricks-training.md}}
317+
318318

319319

320320
### `Microsoft.Automation/automationAccounts/python3Packages/write`, `Microsoft.Automation/automationAccounts/runbooks/write`, `Microsoft.Automation/automationAccounts/runbooks/publish/action`, `Microsoft.Automation/automationAccounts/jobs/write`
@@ -601,3 +601,4 @@ az rest --method GET \
601601
--url "https://management.azure.com/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.Automation/automationAccounts/${AUTOMATION_ACCOUNT}/jobs/${JOB_ID}/streams?api-version=2023-11-01"
602602
```
603603

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

0 commit comments

Comments
 (0)