Skip to content

Commit 1b8bfda

Browse files
committed
Add GitHub workflow specific rules
1 parent b678707 commit 1b8bfda

12 files changed

+801
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
rules:
2+
- id: checkout-pr-on-issue-comment
3+
languages:
4+
- yaml
5+
message: >-
6+
A workflow triggered by an `issue_comment` event is checking out a pull request. This could allow an attacker to inject malicious code by commenting on an issue in a way that causes unintended execution. Ensure proper validation is in place before checking out PRs.
7+
severity: ERROR
8+
patterns:
9+
- pattern-either:
10+
- pattern-inside: |
11+
on:
12+
...
13+
issue_comment: ...
14+
...
15+
...
16+
- pattern-inside: |
17+
on: [..., issue_comment, ...]
18+
...
19+
- pattern-inside: |
20+
on: issue_comment
21+
...
22+
- pattern-inside: |
23+
jobs:
24+
...
25+
$JOBNAME:
26+
...
27+
steps:
28+
...
29+
- pattern: |
30+
run: $CMD
31+
- metavariable-regex:
32+
metavariable: $CMD
33+
regex: ".*gh pr checkout.*"
34+
metadata:
35+
category: security
36+
cwe:
37+
- "CWE-94: Improper Control of Generation of Code ('Code Injection')"
38+
owasp:
39+
- A08:2021 - Software and Data Integrity Failures
40+
references:
41+
- https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#understanding-the-risk-of-script-injections
42+
technology:
43+
- github-actions
44+
- actions/checkout
45+
cwe2022-top25: true
46+
cwe2021-top25: true
47+
subcategory:
48+
- audit
49+
likelihood: MEDIUM
50+
impact: HIGH
51+
confidence: MEDIUM
52+
53+
- id: publish-actions-cache-used
54+
languages:
55+
- yaml
56+
severity: WARNING
57+
metadata:
58+
category: security
59+
cwe:
60+
- "CWE-494: Download of Code Without Integrity Check"
61+
owasp:
62+
- A08:2021 - Software and Data Integrity Failures
63+
references:
64+
- https://github.com/MetaMask/MetaMask-planning/issues/3925
65+
technology:
66+
- github-actions
67+
- actions/cache
68+
cwe2022-top25: true
69+
cwe2021-top25: true
70+
subcategory:
71+
- audit
72+
likelihood: MEDIUM
73+
impact: HIGH
74+
confidence: MEDIUM
75+
tags: [security]
76+
shortDescription: Potential cache poisoning risk by using `actions/cache` in a publishing workflow.
77+
help: |
78+
## Remediation
79+
We recommend avoiding using `actions/cache` if this workflow publishes a release or has access to sensitive secrets.
80+
If caching is required, please see https://github.com/MetaMask/MetaMask-planning/issues/3925 for a workaround.
81+
message: >-
82+
Using GitHub's Action Cache in publishing workflows, especially in open source repositories, can be dangerous. See
83+
https://github.com/MetaMask/MetaMask-planning/issues/3925 for more details and alternative recommendations.
84+
patterns:
85+
- pattern: "uses: $ACTION_NAME"
86+
- metavariable-regex:
87+
metavariable: $ACTION_NAME
88+
regex: actions/cache@.+
89+
paths:
90+
include:
91+
- ".github/**/*publish*.yml"
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
rules:
2+
- id: curl-eval
3+
languages:
4+
- yaml
5+
severity: ERROR
6+
metadata:
7+
tags: [security]
8+
shortDescription: Risk of code injection through curl and eval combination
9+
confidence: LOW
10+
help: |
11+
## Remediation
12+
Avoid eval'ing data fetched from curl commands. If this operation is necessary,
13+
verify the integrity of downloaded content by checking its SHA sum before evaluation.
14+
See GitHub's security guidance for more details on script injection risks.
15+
message: >-
16+
Data is being eval'd from a `curl` command. An attacker with control of the server in the `curl`
17+
command could inject malicious code into the `eval`, resulting in a system compromise. Avoid eval'ing
18+
untrusted data if you can. If you must do this, consider checking the SHA sum of the content returned
19+
by the server to verify its integrity.
20+
patterns:
21+
- pattern-inside: 'steps: [...]'
22+
- pattern-inside: |
23+
- run: ...
24+
...
25+
- pattern: 'run: $SHELL'
26+
- metavariable-pattern:
27+
language: bash
28+
metavariable: $SHELL
29+
patterns:
30+
- pattern: |
31+
$DATA=<... curl ...>
32+
...
33+
eval <... $DATA ...>
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
rules:
2+
- id: github-script-injection
3+
languages:
4+
- yaml
5+
severity: ERROR
6+
metadata:
7+
tags: [security]
8+
shortDescription: Risk of code injection when using `github` context data in `actions/github-script`.
9+
confidence: HIGH
10+
help: |
11+
## Remediation
12+
Instead of using variable interpolation with `github` context data directly in the script,
13+
use an intermediate environment variable:
14+
15+
1. Store the data using `env:`
16+
2. Reference the environment variable in the script using double-quotes: "$ENVVAR"
17+
category: security
18+
cwe:
19+
- "CWE-94: Improper Control of Generation of Code ('Code Injection')"
20+
owasp:
21+
- A03:2021 - Injection
22+
references:
23+
- https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#understanding-the-risk-of-script-injections
24+
- https://securitylab.github.com/research/github-actions-untrusted-input/
25+
- https://github.com/actions/github-script
26+
technology:
27+
- github-actions
28+
cwe2022-top25: true
29+
subcategory:
30+
- vuln
31+
likelihood: HIGH
32+
impact: HIGH
33+
message: >-
34+
Using variable interpolation `${{...}}` with `github` context data in a `actions/github-script`'s
35+
`script:` step could allow an attacker to inject their own code into the runner. This would allow them to steal secrets and code. `github` context
36+
data can have arbitrary user input and should be treated as untrusted. Instead, use an intermediate environment
37+
variable with `env:` to store the data and use the environment variable in the `run:` script. Be sure to use double-quotes
38+
the environment variable, like this: "$ENVVAR".
39+
patterns:
40+
- pattern-inside: 'steps: [...]'
41+
- pattern-inside: |
42+
uses: $ACTION
43+
...
44+
- pattern-inside: |
45+
with:
46+
...
47+
script: ...
48+
...
49+
- pattern: 'script: $SHELL'
50+
- metavariable-regex:
51+
metavariable: $ACTION
52+
regex: actions/github-script@.*
53+
- metavariable-pattern:
54+
language: generic
55+
metavariable: $SHELL
56+
patterns:
57+
- pattern-either:
58+
- pattern: ${{ github.event.issue.title }}
59+
- pattern: ${{ github.event.issue.body }}
60+
- pattern: ${{ github.event.pull_request.title }}
61+
- pattern: ${{ github.event.pull_request.body }}
62+
- pattern: ${{ github.event.comment.body }}
63+
- pattern: ${{ github.event.review.body }}
64+
- pattern: ${{ github.event.review_comment.body }}
65+
- pattern: ${{ github.event.pages. ... .page_name}}
66+
- pattern: ${{ github.event.head_commit.message }}
67+
- pattern: ${{ github.event.head_commit.author.email }}
68+
- pattern: ${{ github.event.head_commit.author.name }}
69+
- pattern: ${{ github.event.commits ... .author.email }}
70+
- pattern: ${{ github.event.commits ... .author.name }}
71+
- pattern: ${{ github.event.pull_request.head.ref }}
72+
- pattern: ${{ github.event.pull_request.head.label }}
73+
- pattern: ${{ github.event.pull_request.head.repo.default_branch }}
74+
- pattern: ${{ github.head_ref }}
75+
- pattern: ${{ github.event.inputs ... }}
76+
- pattern: ${{ github.event.discussion.title }}
77+
- pattern: ${{ github.event.discussion.body }}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
rules:
2+
- id: pull-request-target-code-checkout
3+
languages:
4+
- yaml
5+
message: >-
6+
This GitHub Actions workflow file uses `pull_request_target` and checks out code
7+
from the incoming pull request. When using `pull_request_target`, the Action
8+
runs in the context of the target repository, which includes access to all repository
9+
secrets. Normally, this is safe because the Action only runs code from the target
10+
repository, not the incoming PR. However, by checking out the incoming PR code, you're now using
11+
the incoming code for the rest of the action. You may be inadvertently executing arbitrary code
12+
from the incoming PR with access to repository secrets, which would let an attacker steal repository
13+
secrets.
14+
This normally happens by running build scripts (e.g., `npm build` and `make`) or dependency installation
15+
scripts (e.g., `python setup.py install`).
16+
Audit your workflow file to make sure no code from the incoming PR is executed.
17+
Please see https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ for additional
18+
mitigations.
19+
metadata:
20+
tags: [security]
21+
shortDescription: Unsafe code checkout in pull_request_target workflow
22+
confidence: LOW
23+
help: |
24+
## Remediation
25+
When using `pull_request_target`, avoid checking out code from the incoming PR. If you must check out PR code,
26+
ensure no untrusted code is executed (including build scripts and dependency installation).
27+
See https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ for additional mitigations.
28+
category: security
29+
owasp:
30+
- A01:2021 - Broken Access Control
31+
cwe:
32+
- 'CWE-913: Improper Control of Dynamically-Managed Code Resources'
33+
references:
34+
- https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
35+
- https://github.com/justinsteven/advisories/blob/master/2021_github_actions_checkspelling_token_leak_via_advice_symlink.md
36+
technology:
37+
- github-actions
38+
subcategory:
39+
- audit
40+
likelihood: LOW
41+
impact: MEDIUM
42+
patterns:
43+
- pattern-either:
44+
- pattern-inside: |
45+
on:
46+
...
47+
pull_request_target: ...
48+
...
49+
...
50+
- pattern-inside: |
51+
on: [..., pull_request_target, ...]
52+
...
53+
- pattern-inside: |
54+
on: pull_request_target
55+
...
56+
- pattern-inside: |
57+
jobs:
58+
...
59+
$JOBNAME:
60+
...
61+
steps:
62+
...
63+
- pattern: |
64+
...
65+
uses: "$ACTION"
66+
with:
67+
...
68+
ref: $EXPR
69+
- metavariable-regex:
70+
metavariable: $ACTION
71+
regex: actions/checkout@.*
72+
- metavariable-pattern:
73+
language: generic
74+
metavariable: $EXPR
75+
patterns:
76+
- pattern: ${{ github.event.pull_request ... }}
77+
severity: WARNING
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
rules:
2+
- id: run-shell-injection
3+
languages:
4+
- yaml
5+
message: 'Using variable interpolation `${{...}}` with `github` context data in a `run:` step could
6+
allow an attacker to inject their own code into the runner. This would allow them to steal secrets
7+
and code. `github` context data can have arbitrary user input and should be treated as untrusted.
8+
Instead, use an intermediate environment variable with `env:` to store the data and use the environment
9+
variable in the `run:` script. Be sure to use double-quotes the environment variable, like this: "$ENVVAR".'
10+
metadata:
11+
category: security
12+
cwe:
13+
- "CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')"
14+
owasp:
15+
- A01:2017 - Injection
16+
- A03:2021 - Injection
17+
references:
18+
- https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#understanding-the-risk-of-script-injections
19+
- https://securitylab.github.com/research/github-actions-untrusted-input/
20+
technology:
21+
- github-actions
22+
cwe2022-top25: true
23+
cwe2021-top25: true
24+
subcategory:
25+
- vuln
26+
likelihood: HIGH
27+
impact: HIGH
28+
confidence: HIGH
29+
tags: [security]
30+
shortDescription: Shell injection risk in GitHub Actions run steps
31+
help: |
32+
## Remediation
33+
Instead of using `github` context data directly in `run:` steps, use an intermediate environment variable:
34+
```yaml
35+
steps:
36+
- run: echo "$MY_VAR"
37+
env:
38+
MY_VAR: ${{ github.event.issue.title }}
39+
```
40+
patterns:
41+
- pattern-inside: 'steps: [...]'
42+
- pattern-inside: |
43+
- run: ...
44+
...
45+
- pattern: 'run: $SHELL'
46+
- metavariable-pattern:
47+
language: generic
48+
metavariable: $SHELL
49+
patterns:
50+
- pattern-either:
51+
- pattern: ${{ github.event.issue.title }}
52+
- pattern: ${{ github.event.issue.body }}
53+
- pattern: ${{ github.event.pull_request.title }}
54+
- pattern: ${{ github.event.pull_request.body }}
55+
- pattern: ${{ github.event.comment.body }}
56+
- pattern: ${{ github.event.review.body }}
57+
- pattern: ${{ github.event.review_comment.body }}
58+
- pattern: ${{ github.event.pages. ... .page_name}}
59+
- pattern: ${{ github.event.head_commit.message }}
60+
- pattern: ${{ github.event.head_commit.author.email }}
61+
- pattern: ${{ github.event.head_commit.author.name }}
62+
- pattern: ${{ github.event.commits ... .author.email }}
63+
- pattern: ${{ github.event.commits ... .author.name }}
64+
- pattern: ${{ github.event.pull_request.head.ref }}
65+
- pattern: ${{ github.event.pull_request.head.label }}
66+
- pattern: ${{ github.event.pull_request.head.repo.default_branch }}
67+
- pattern: ${{ github.head_ref }}
68+
- pattern: ${{ github.event.inputs ... }}
69+
- pattern: ${{ github.event.discussion.title }}
70+
- pattern: ${{ github.event.discussion.body }}
71+
severity: ERROR

0 commit comments

Comments
 (0)