This blog shows another case of a GitHub Actions environment injection vulnerability in a Google repository. We previously found vulnerabilities in Firebase repositories and a detailed explanation can be found here including the underline mechanism that allows this type of vulnerability. By exploiting this latest vulnerability an attack could put Google’s Orbit users and maintainers at risk by injecting malicious code, conducting phishing attacks and more, depending on the project specific configuration.
Google Orbit
Google’s Orbit (open run time binary instrumentation tool) is a binary profiling application. Its main purpose is to help developers identify performance bottlenecks in a complex application.
The repository contained two similar vulnerable workflows:
-
“.github/workflows/report-checks.yml”
-
“.github/workflows/report-build-and-test.yml”
(Content of report-checks.yml)
name: report-checks
on:
workflow_run:
workflows: ['checks']
types:
- completed
permissions: read-all
jobs:
report-missing-license-headers:
permissions:
checks: write
statuses: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: '0'
- name: Download artifact
uses: dawidd6/action-download-artifact@e6e25ac3a2b93187502a8be1ef9e9603afc34925 # v2.24.2
with:
workflow: $
workflow_conclusion: ''
name: missing_license_headers
- name: Report missing headers
run: ./contrib/scripts/report-license-headers.sh
env:
GITHUB_TOKEN: $
COMMIT_SHA: $
shell: bash
report-clang-format-diff:
permissions:
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Download artifact
uses: dawidd6/action-download-artifact@e6e25ac3a2b93187502a8be1ef9e9603afc34925 # v2.24.2
with:
workflow: $
workflow_conclusion: ''
- run: echo "PR_NUMBER=$(cat pr_number/pr_number.txt | jq -r .)" >> $GITHUB_ENV
This workflow does the following operations:
- It is triggered whenever a workflow named “checks” finishes
on:
workflow_run:
workflows: ['checks']
- It downloads an artifact that it expects to be previously uploaded by the “checks” workflow
- name: Download artifact
uses: dawidd6/action-download-artifact@e6e25ac3a2b93187502a8be1ef9e9603afc34925 # v2.24.2
with:
workflow: $
workflow_conclusion: '
- It then reads the pull-request number from artifact and writes it into the ‘pr_number' environment variable
- run: echo "PR_NUMBER=$(cat pr_number/pr_number.txt | jq -r .)" >> $GITHUB_ENV
Where is the problem
The uploaded artifact is controlled by a potentially malicious actor. This means an adversary could trick the privileged “report-checks” workflow to write malicious content into the GITHUB_ENV file.
As explained in part 3 of the series, by controlling the content written to the GITHUB_ENV file attacker can gain code execution on the privilege workflow.
For example, to dump the runner environment variables, the following environment could be set:
NODE_OPTIONS=--experimental-modules
--experimental-loader=data:text/javascript,console.log(Buffer.from(JSON.stringify(process.env)).toSt
ring('hex'));
The exploitation flow:
1. Fork the repository
2. Create a workflow ".github/workflows/exploit.yml" with the following payload:
3. Open a pull request to base repository
4. The completion of the malicious workflow will trigger the vulnerable workflow and the exploitation flow.
Consequences:
The vulnerable job has access to a GitHub token with 'pull-request: write' scope and a GitHub token name 'ORBITPROFILER_BOT_PAT'
An attacker can use the exfiltrated GITHUB_TOKEN to perform a variety of malicious activities, such as:
-
Approving malicious pull requests
-
Commenting on pull_requests / issues with malicious links
-
Additional malicious activity depending on the permissions of 'ORBITPROFILER_BOT_PAT' and on the repository’s specific configurations
What Can You Do to Protect Yourselves
-
Never write untrusted input data to the environment file
-
Restrict the GitHub token permissions only to the required ones; this way, even if an attacker succeeds in compromising your workflow, they won’t be able to do much
-
Prefer using Actions output parameters instead of environment variables
-
If possible, check that the triggering workflow doesn’t belong to a forked repository, and if it does require human approval, as explained in this blog post: Using Environment Protection Rules to Secure Secrets When Building External Forks with pull_request_target
Timeline
-
May 17: reported issue to Google through their bug bounty program
-
May 18, Google acknowledged the issue
-
May 22: Google removed the vulnerable code Remove Report Workflows (#4830) · google/orbit@6cd71a3 and stated that the repository is old and not currently maintained
-
June 7: Received bounty (that we’ll donate)
Legit Security Can Help You Prevent Software Supply Chain Attacks
The Legit Security platform connects to your GitHub organization and detects vulnerable workflows such as this one in real-time and much more. If you are concerned about these vulnerabilities and others across your software supply chain, please contact us or request a demo on our website.
Ready to learn more? Schedule a product demo or check out the Legit Security Platform.