Skip to content

Commit cf58e83

Browse files
authored
Add semgrep checks for pinned actions. (#26)
* Add semgrep tests for pinned actions. This will look at all workflow files and look at: ``` uses: org/repo@v5 ``` and encourage users to instead pin those to git commits. * Fix mdformat. * Use ratchet to pin all our action usage references. * Fix message to also include link to docs. * Add additional test case. * Fix yaml format.
1 parent e0df38f commit cf58e83

File tree

8 files changed

+78
-8
lines changed

8 files changed

+78
-8
lines changed

.github/workflows/markdown_format.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ jobs:
1010
runs-on: 'ubuntu-latest'
1111
steps:
1212
- name: 'Checkout Code'
13-
uses: 'actions/checkout@v4'
13+
uses: 'actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683' # ratchet:actions/checkout@v4
1414
- name: 'Check Markdown Format'
1515
run: 'tools/mdformat --check --wrap 100 .'

.github/workflows/publish_docs.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ jobs:
1515
name: "Build and Deploy Docs"
1616
runs-on: 'ubuntu-latest'
1717
steps:
18-
- uses: 'actions/checkout@v4'
18+
- uses: 'actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683' # ratchet:actions/checkout@v4
1919
- name: 'Generate HTML from Markdown'
20-
uses: 'ldeluigi/markdown-docs@latest'
20+
uses: 'ldeluigi/markdown-docs@e51f9a21070db6a21dfbe27ac92f065823e006a1' # ratchet:ldeluigi/markdown-docs@latest
2121
with:
2222
src: 'docs'
2323
dst: 'generated-pages'
2424
- name: 'Install rsync'
2525
run: 'apt-get update && apt-get install -y rsync'
2626
- name: 'Deploy Docs'
27-
uses: JamesIves/github-pages-deploy-action@v4
27+
uses: JamesIves/github-pages-deploy-action@6c2d9db40f9296374acc17b90404b6e8864128c8 # ratchet:JamesIves/github-pages-deploy-action@v4
2828
with:
2929
folder: generated-pages
3030
force: false

.github/workflows/publish_docs_preview.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ jobs:
1414
name: "Build PR Preview Docs"
1515
runs-on: 'ubuntu-latest'
1616
steps:
17-
- uses: 'actions/checkout@v4'
17+
- uses: 'actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683' # ratchet:actions/checkout@v4
1818
- name: 'Generate HTML from Markdown'
19-
uses: 'ldeluigi/markdown-docs@latest'
19+
uses: 'ldeluigi/markdown-docs@e51f9a21070db6a21dfbe27ac92f065823e006a1' # ratchet:ldeluigi/markdown-docs@latest
2020
with:
2121
src: 'docs'
2222
dst: 'generated-pages'
2323
- name: 'Deploy GitHub Pages Preview'
24-
uses: rossjrw/pr-preview-action@v1
24+
uses: rossjrw/pr-preview-action@df22037db54ab6ee34d3c1e2b8810ac040a530c6 # ratchet:rossjrw/pr-preview-action@v1
2525
with:
2626
source-dir: './generated-pages/'

.github/workflows/yaml_format.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ jobs:
1111
runs-on: 'ubuntu-latest'
1212
steps:
1313
- name: 'Checkout Code'
14-
uses: 'actions/checkout@v4'
14+
uses: 'actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683' # ratchet:actions/checkout@v4
1515
- name: 'Check Yaml Format'
1616
run: 'tools/yamlfmt --lint .'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# actions-need-pinned-commits
2+
3+
For actions that look like:
4+
5+
```
6+
uses: actions/checkout@v4
7+
```
8+
9+
GitHub uses the underlying git label v4 to fetch the action to run. As seen in the
10+
[tj-actions/changed-files](https://semgrep.dev/blog/2025/popular-github-action-tj-actionschanged-files-is-compromised/)
11+
vulnerabilty, these lables are not immutable and trivially changeable. So what you think is a nice
12+
stable safe version, an attacker has changed behind your back to something nefarious.
13+
14+
We are strongly encouraging use to use the full git commit hash instead to prevent this type of
15+
attacks.
16+
17+
## Ratchet
18+
19+
[Ratchet](https://github.com/sethvargo/ratchet) provides an easy way to do this.
20+
21+
You can pin all your workflow files like this:
22+
23+
```
24+
ratchet pin .github/workflows/*
25+
```
26+
27+
And upgrade them (as needed, under your control and not someone elses):
28+
29+
```
30+
ratchet upgrade .github/workflows/action_to_upgrade.yml
31+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
rules:
2+
- id: actions-need-pinned-commits
3+
languages:
4+
- yaml
5+
severity: WARNING
6+
message: 'Referencing an action to run by git tag is risky, due to the mutability of git tags. Prefer
7+
to use full git SHAs instead. More information: https://google.github.io/github-team/semgrep-rules/actions-need-pinned-commits.html'
8+
metadata:
9+
category: best-practice
10+
technology:
11+
- github-actions
12+
patterns:
13+
- pattern-either:
14+
- patterns:
15+
- pattern-inside: "{steps: ...}"
16+
# Match all uses patterns that don't contain the full SHA1 hash. Yes, short hashes exist but suffer from a similar (but slightly harder) attack vector by purposely crafting a colliding SHA.
17+
- pattern: "uses: ..."
18+
- pattern-not-regex: ".*@[0-9A-Fa-f]{40}.*"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: 'Test Actions Needing Pinned Commits'
2+
on:
3+
pull_request:
4+
jobs:
5+
do-stuff:
6+
steps:
7+
- name: 'Step 1'
8+
# ruleid: actions-need-pinned-commits
9+
uses: actions/checkout@v4
10+
- name: 'Step 2'
11+
uses: 'actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683'
12+
- name: 'Step 2.5'
13+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4
14+
- name: 'Step 3'
15+
# ruleid: actions-need-pinned-commits
16+
uses: 'actions/checkout@11bd719'
17+
- name: 'Step 4'
18+
# ruleid: actions-need-pinned-commits
19+
uses: 'actions/checkout@my_git_label'

tools/ratchet

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/sh
2+
docker run -it --rm -v "${PWD}:${PWD}" -w "${PWD}" ghcr.io/sethvargo/ratchet:latest $*

0 commit comments

Comments
 (0)