Summary

The design and promoted usage examples of awslabs/one-line-scan makes consuming workflows vulnerable to arbitrary code execution.

Product

Tested Version

The latest changesets to the date be492f8 and 19c8bfe.

Details

pull_request_target was introduced to allow triggered workflows to comment on PRs, label them, assign people, etc.. In order to make it possible the triggered action runner has read/write token for the base repository and the access to secrets. In order to prevent untrusted code from execution it runs in a context of the base repository.

By explicitly checking out and running build script from a fork the untrusted code is running in an environment that is able to push to the base repository and to access secrets.

Issue: awslabs/one-line-scan is designed to run potentially untrusted code from a Pull Request on pull_request_target

Below is an excerpt from an example of usage in the documentation:

on:
pull_request_target:
  # [ACTION REQUIRED] Set the branch you want to analyze PRs for
  branches:
    - '**'
...
    # Get the code, fetch the full history to make sure we have the compare commit as well
    steps:
    - uses: actions/checkout@v2
    with:
        fetch-depth: 0
...
    # Get the reference remote
    - name: Setup Reference Commit Remote
    # [ACTION REQUIRED] Add the https URL of your repository
    run: git remote add reference https://github.com/awslabs/ktf.git
    - name: Fetch Reference Commit Remote
    run: git fetch reference

    # Get one-line-scan, the tool we will use for analysis
    - name: Get OneLineScan
    run:  git clone -b one-line-cr-bot https://github.com/awslabs/one-line-scan.git ../one-line-scan
...
    # Run the analysis, parameterized for this package
    - name: one-line-cr-analysis
    env:
        # [ACTION REQUIRED] Adapt the values below accordingly
        # 'reference' is the name of the remote to use
        # PR local: ${{github.event.pull_request.head.repo.full_name}}/${{github.event.pull_request.head.ref}}
        BASE_COMMIT: "reference/mainline"
        BUILD_COMMAND: "make -B all"
        CLEAN_COMMAND: "make clean"
...
    # Be explicit about the tools to be used
    run: ../one-line-scan/one-line-cr-bot.sh -E infer -E cppcheck
...

Since the action needs repository write token for functioning and worklows triggered on pull_request do not have the access to secrets it promotes using pull_request_target and explicitly checking out the code from the Pull Request. Even though the example by mistake checks out not the PR branch, but the base, the affected awslabs/ktf has fixed the error and actually checks out the PR:

    # Get the code, fetch the full history to make sure we have the compare commit as well
    - uses: actions/checkout@v2
      with:
        fetch-depth: 0
        ref: ${{github.event.pull_request.head.ref}}
        repository: ${{github.event.pull_request.head.repo.full_name}}

One of the tool’s arguments is a BUILD_COMMAND script. A potentially untrusted Pull Request may execute an arbitrary script in a workflow that has read/write repository access and potentially can access secrets.

Impact

The vulnerability allows for unauthorized modification of the using repository and secrets exfiltration.

Coordinated Disclosure Timeline

Credit

This issue was discovered and reported by GHSL team member @JarLob (Jaroslav Lobačevski).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2020-288 in any communication regarding this issue.