yaml.github-actions.security.workflow-run-target-code-checkout.workflow-run-target-code-checkout

This GitHub Actions workflow file uses workflow_run
and checks out code from the incoming pull request. When using workflow_run
, 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: workflow-run-target-code-checkout
languages:
- yaml
message: This GitHub Actions workflow file uses `workflow_run` and checks out
code from the incoming pull request. When using `workflow_run`, 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:2017 - Injection
cwe: "CWE-913: Improper Control of Dynamically-Managed Code Resources"
likelihood: MEDIUM
impact: MEDIUM
confidence: MEDIUM
subcategory:
- vuln
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
- https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability
technology:
- github-actions
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Code Injection
patterns:
- pattern-inside: |
on:
...
workflow_run: ...
...
...
- 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.workflow_run ... }}
severity: WARNING
Examples
workflow-run-target-code-checkout.test.yaml
on:
# pull_request_target:
workflow_run:
workflows: ["smth-else"]
types:
- completed
pull_request:
jobs:
build:
name: Build and test
runs-on: ubuntu-latest
steps:
# ruleid: workflow-run-target-code-checkout
- uses: actions/checkout@v2
with:
ref: ${{ github.event.workflow_run.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: workflow-run-target-code-checkout
- uses: actions/checkout@v2.3.4
with:
ref: ${{ github.event.workflow_run.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: workflow-run-target-code-checkout
- name: echo
run: |
echo "Hello, world"
spelling:
name: Spell checking
runs-on: ubuntu-latest
steps:
# ruleid: workflow-run-target-code-checkout
- name: checkout-merge
if: contains(github.event_name, 'pull_request')
uses: actions/checkout@v2
with:
ref: refs/pull/${{github.event.workflow_run.number}}/merge