Skip to content

Commit 4e231a9

Browse files
authored
ci: harden workflows against script injection (#222)
Pass inputs.bump, the App slug and the PR number to run steps through env instead of interpolating ${{ }} into the shell script, which Aikido flags as template injection (critical, cut-release.yml). Also set persist-credentials explicitly on every checkout: false where the job never pushes, true in cut-release where release.sh pushes the release branch and tag.
1 parent 6047201 commit 4e231a9

6 files changed

Lines changed: 24 additions & 5 deletions

File tree

‎.github/workflows/check-release.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ jobs:
1616
steps:
1717
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
1818
with:
19+
persist-credentials: false
1920
fetch-depth: 0
2021

2122
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6

‎.github/workflows/cut-release.yml‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ jobs:
5252
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
5353
with:
5454
token: ${{ steps.app-token.outputs.token }}
55+
persist-credentials: true # release.sh pushes the branch / tag
5556
fetch-depth: 0
5657
fetch-tags: true
5758

@@ -66,8 +67,9 @@ jobs:
6667
- name: Configure git identity
6768
env:
6869
GH_TOKEN: ${{ steps.app-token.outputs.token }}
70+
APP_SLUG: ${{ steps.app-token.outputs.app-slug }}
6971
run: |
70-
slug="${{ steps.app-token.outputs.app-slug }}[bot]"
72+
slug="${APP_SLUG}[bot]"
7173
id="$(gh api "/users/${slug}" --jq .id)"
7274
git config user.name "$slug"
7375
git config user.email "${id}+${slug}@users.noreply.github.com"
@@ -81,7 +83,10 @@ jobs:
8183
- name: Prepare release
8284
env:
8385
GH_TOKEN: ${{ steps.app-token.outputs.token }}
84-
run: ./scripts/release.sh prepare "${{ inputs.bump }}"
86+
# Via env, not ${{ }} in the script: the input is free text and
87+
# interpolating it into `run` would execute anything shell-shaped.
88+
BUMP: ${{ inputs.bump }}
89+
run: ./scripts/release.sh prepare "$BUMP"
8590

8691
# Branch protection on main gates the merge on the checks and the
8792
# approving review, so this only merges once everything is green.
@@ -115,6 +120,7 @@ jobs:
115120
with:
116121
ref: main
117122
token: ${{ steps.app-token.outputs.token }}
123+
persist-credentials: true # release.sh pushes the branch / tag
118124
fetch-depth: 0
119125
fetch-tags: true
120126

@@ -125,8 +131,9 @@ jobs:
125131
- name: Configure git identity
126132
env:
127133
GH_TOKEN: ${{ steps.app-token.outputs.token }}
134+
APP_SLUG: ${{ steps.app-token.outputs.app-slug }}
128135
run: |
129-
slug="${{ steps.app-token.outputs.app-slug }}[bot]"
136+
slug="${APP_SLUG}[bot]"
130137
id="$(gh api "/users/${slug}" --jq .id)"
131138
git config user.name "$slug"
132139
git config user.email "${id}+${slug}@users.noreply.github.com"

‎.github/workflows/integration-tests.yml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ jobs:
2727
private-key: ${{ secrets.HOTDATA_AUTOMATION_PRIVATE_KEY }}
2828
owner: hotdata-dev
2929
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
30+
with:
31+
persist-credentials: false
3032
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
3133
with:
3234
python-version: '3.12'
@@ -70,6 +72,8 @@ jobs:
7072
runs-on: ubuntu-latest
7173
steps:
7274
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
75+
with:
76+
persist-credentials: false
7377
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
7478
with:
7579
python-version: '3.12'
@@ -87,6 +91,8 @@ jobs:
8791
runs-on: ubuntu-latest
8892
steps:
8993
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
94+
with:
95+
persist-credentials: false
9096
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
9197
with:
9298
python-version: '3.12'

‎.github/workflows/publish.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ jobs:
5151
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
5252
with:
5353
ref: ${{ env.RELEASE_TAG }}
54+
persist-credentials: false
5455

5556
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
5657
with:

‎.github/workflows/regenerate.yml‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ jobs:
2727
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
2828
with:
2929
token: ${{ steps.app-token.outputs.token }}
30+
# create-pull-request authenticates its own push from `token`.
31+
persist-credentials: false
3032
fetch-depth: 0
3133
fetch-tags: true
3234

@@ -337,7 +339,8 @@ jobs:
337339
if: steps.cpr.outputs.pull-request-number
338340
env:
339341
GH_TOKEN: ${{ steps.app-token.outputs.token }}
342+
PR_NUMBER: ${{ steps.cpr.outputs.pull-request-number }}
340343
run: |
341-
gh pr merge "${{ steps.cpr.outputs.pull-request-number }}" \
342-
--repo "${{ github.repository }}" \
344+
gh pr merge "$PR_NUMBER" \
345+
--repo "$GITHUB_REPOSITORY" \
343346
--squash --auto

‎.github/workflows/release.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ jobs:
3737
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
3838
with:
3939
ref: ${{ env.RELEASE_TAG }}
40+
persist-credentials: false
4041
fetch-depth: 0
4142

4243
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6

0 commit comments

Comments
 (0)