Suppose you have a Github Actions script like below:
The script will be triggered when a new issue comment is added to the issue or a comment is edited.
name: GitHub Actions Demo
on:
issue_comment:
types: [created, edited]
jobs:
Explore-GitHub-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- run: echo ${{ github.event.comment.body }}
Notice that ${{ github.event.comment.body }}
is used in the run
step directly? This makes the script vulnerable to Command Injection. Why?
Read this: https://securitylab.github.com/research/github-actions-untrusted-input/#remediation
In this context, someone can inject commands to the GH Action script by adding their payload to the issue comment. The GH Action script is triggered every time there is a new issue comment.

Did you notice we can run echo bye
? This is just a simple example but worse scenario can be reverse-shell (if you are using self-hosted GH Runners) or secrets theft.

You can even attack in a stealth mode by deleting the comment immediately once the workflow is triggered.

How to prevent the issue?
Set the github context data in env variable before you use it in the run
[...]
- env: # Add this
BODY: ${{ github.event.comment.body }} # Add this
run: echo "$BODY"
Add a new comment that contains a payload:

You can see the script is interpreting the comment body as string rather than interpolating it as a command to execute.
