Skip to content

Latest commit

 

History

History
55 lines (33 loc) · 3.69 KB

pwn-request-via-non-default-branch.md

File metadata and controls

55 lines (33 loc) · 3.69 KB

Pwn Request via non-default branch

After reading the Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests blog post I digged deeper into the vulnerability and found that many maintainers fall into the same pitfall while remediating the Pwn Request vulnerability. This discovery led to 8 fix bypasses immideately and several later.

How the bypass works?

The bypass uses the fact that the pull_request_target event runs workflows from a target branch (in contrast to most other events that always run workflows from the default branch). So by changing the target branch one can bypass a fix.

Consider the following scenario:

  1. A workflow with the Pwn Request vulnerability is committed to the default branch of a repository.
  2. Maintainers create new branches from the default branch. In this way vulnerability propogates to another branches.
  3. The vulnerability gets fixed in the default branch.
  4. However, the non-default branches still contain the vulnerability.

If a malicious user creates a pull request against a non-default branch in which the vulnerable workflow still exist, the vulnerable version of the workflow will be executed, not the fixed one. In this way the malicious user will bypass the fix.

How branches and branches-ignore can (unintentionally) prevent the bypass?

Having a vulnerable workflow in a non-default branch is not always exploitable. When using the pull_request and pull_request_target events, one can configure a workflow to run only for pull requests that target specific branches using the branches and branches-ignore filters.

For example, the continuous-integration.yml workflow had a pwn request vulnerability (GHSL-2020-249). Maintainers applied the fix only to the default branch. However, the workflow runs only on pull requests to the master and release-1.x branches:

name: CI Workflow

on:
  pull_request_target:
    branches:
      - master
      - release-1.x
...

The vulnerability was fixed at master and branches matching the release-1.x pattern didn't contain the vulnerable workflow thus it was not possible to run the workflow by targeting another branch so it was not possible to bypass the fix.

Example

Environment setup

Run setup-bypass-another-branch.sh as the victim to create a repository with two branches. The default branch is safe while the other branch is unsafe.

You'll need gh installed to execute the setup-bypass-another-branch.sh script

Proof of concept

TODO: write-up the proof of concept

Remediation

The remediation is straightforward. When fixing the Pwn Request vulnerability either (1) fix it in all branches or (2) fix it in the default branch and delete all non-default branches that contain the vulnerable workflow.

Automation

Some repositories have a lot of branches and workflows so checking every branch and workflow manually would be at least tedious. I've created the bypass-another-branch.sh script that goes through each branch and extracts unique workflow files.