yaml.github-actions.security.pull-request-target-code-checkout.pull-request-target-code-checkout

This GitHub Actions workflow file uses pull_request_target
and checks out code from the incoming pull request. When using pull_request_target
, the Action runs in the context of the target repository, which includes access to all repository secrets. Normally, this is safe because the Action only runs code from the target repository, not the incoming PR. However, by checking out the incoming PR code, you're now using the incoming code for the rest of the action. You may be inadvertently executing arbitrary code from the incoming PR with access to repository secrets, which would let an attacker steal repository secrets. This normally happens by running build scripts (e.g., npm build
and make
) or dependency installation scripts (e.g., python setup.py install
). Audit your workflow file to make sure no code from the incoming PR is executed. Please see https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ for additional mitigations.
Run Locally
Run in CI
Defintion
rules:
- id: pull-request-target-code-checkout
languages:
- yaml
message: This GitHub Actions workflow file uses `pull_request_target` and checks
out code from the incoming pull request. When using `pull_request_target`,
the Action runs in the context of the target repository, which includes
access to all repository secrets. Normally, this is safe because the
Action only runs code from the target repository, not the incoming PR.
However, by checking out the incoming PR code, you're now using the
incoming code for the rest of the action. You may be inadvertently
executing arbitrary code from the incoming PR with access to repository
secrets, which would let an attacker steal repository secrets. This
normally happens by running build scripts (e.g., `npm build` and `make`)
or dependency installation scripts (e.g., `python setup.py install`).
Audit your workflow file to make sure no code from the incoming PR is
executed. Please see
https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
for additional mitigations.
metadata:
category: security
owasp:
- A01:2021 - Broken Access Control
cwe:
- "CWE-913: Improper Control of Dynamically-Managed Code Resources"
references:
- https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
- https://github.com/justinsteven/advisories/blob/master/2021_github_actions_checkspelling_token_leak_via_advice_symlink.md
technology:
- github-actions
subcategory:
- audit
likelihood: LOW
impact: MEDIUM
confidence: LOW
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
patterns:
- pattern-either:
- pattern-inside: |
on:
...
pull_request_target: ...
...
...
- pattern-inside: |
on: [..., pull_request_target, ...]
...
- pattern-inside: |
on: pull_request_target
...
- pattern-inside: |
jobs:
...
$JOBNAME:
...
steps:
...
- pattern: |
...
uses: "$ACTION"
with:
...
ref: $EXPR
- metavariable-regex:
metavariable: $ACTION
regex: actions/checkout@.*
- metavariable-pattern:
language: generic
metavariable: $EXPR
patterns:
- pattern: ${{ github.event.pull_request ... }}
severity: WARNING
Examples
pull-request-target-code-checkout.test.yaml
# cf. https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
# INSECURE. Provided as an example only.
on:
pull_request_target:
pull_request:
jobs:
build:
name: Build and test
runs-on: ubuntu-latest
steps:
# ruleid: pull-request-target-code-checkout
- uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-node@v1
- run: |
npm install
npm build
- uses: completely/fakeaction@v2
with:
arg1: ${{ secrets.supersecret }}
- uses: fakerepo/comment-on-pr@v1
with:
message: |
Thank you!
build2:
name: Build and test 2
runs-on: ubuntu-latest
steps:
# ruleid: pull-request-target-code-checkout
- uses: actions/checkout@v2.3.4
with:
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-node@v1
- run: |
npm install
npm build
- uses: completely/fakeaction@v2
with:
arg1: ${{ secrets.supersecret }}
- uses: fakerepo/comment-on-pr@v1
with:
message: |
Thank you!
this-is-safe-because-no-checkout:
name: Echo
runs-on: ubuntu-latest
steps:
# ok: pull-request-target-code-checkout
- name: echo
run: |
echo "Hello, world"
# cf. https://github.com/justinsteven/advisories/blob/master/2021_github_actions_checkspelling_token_leak_via_advice_symlink.md
spelling:
name: Spell checking
runs-on: ubuntu-latest
steps:
# ruleid: pull-request-target-code-checkout
- name: checkout-merge
if: contains(github.event_name, 'pull_request')
uses: actions/checkout@v2
with:
ref: refs/pull/${{github.event.pull_request.number}}/merge