Coordinated Disclosure Timeline

Summary

The ci.yml GitHub workflow is vulnerable to unauthorized modification of the base repository or secrets exfiltration from a Pull Request.

Product

libpasta/libpasta GitHub repository

Tested Version

The latest changeset 3921c89 to the date.

Details

Issue: Untrusted code is explicitly checked out and run on a Pull Request from a fork

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

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

on:
...
  pull_request_target:
...
      - uses: actions/checkout@v2
        with:
          # This prevents the Action from persisting the credentials it uses to
          # perform the fetch/checkout to the Runner's local Git config. On
          # `pull_request_target` events, the GITHUB_TOKEN provided to the
          # Runner has Write permissions to the base repository. We do **not**
          # want to allow untrusted code from forks to execute arbitrary Git
          # commands with those elevated permissions.
          #
          # More info:
          # https://github.blog/2020-08-03-github-actions-improvements-for-fork-and-pull-request-workflows/#improvements-for-public-repository-forks
          persist-credentials: false
          # Explicitly setting the `repository` and `ref` inputs ensures that
          # `pull_request_target` events trigger CI runs against the code from
          # the HEAD branch. By default, this Action checks out code from the
          # BASE branch. On `push` events, the `github.event.pull_request` path
          # will yield a null value, and passing nulls to these inputs causes
          # them to fall back to the defaults
          repository: ${{ github.event.pull_request.head.repo.full_name }}
          ref: ${{ github.event.pull_request.head.sha }}
...
      - name: Run test
        run: cargo test --all-targets --features long_tests
...

Impact

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

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-335 in any communication regarding this issue.