Skip to content

Commit 2fa8e16

Browse files
vaindclaude
andcommitted
fix(updater): Prevent script injection vulnerabilities
Add input validation and use environment variables instead of direct interpolation to prevent potential script injection attacks through user-controlled workflow inputs. - Add validate-inputs job to check for safe characters in inputs.name and inputs.path - Move all environment variable declarations to job level for better organization - Replace direct interpolation in PR titles and PowerShell scripts with env variables - Ensure all user inputs are properly sanitized before use 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 1949ea0 commit 2fa8e16

File tree

1 file changed

+38
-14
lines changed

1 file changed

+38
-14
lines changed

.github/workflows/updater.yml

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,23 @@ jobs:
7272
with:
7373
access_token: ${{ github.token }}
7474

75+
validate-inputs:
76+
runs-on: ubuntu-latest
77+
steps:
78+
- name: Validate inputs
79+
run: |
80+
# Validate that inputs.name contains only safe characters
81+
if [[ ! "${{ inputs.name }}" =~ ^[a-zA-Z0-9_\-\./@ ]+$ ]]; then
82+
echo "::error::Invalid dependency name: '${{ inputs.name }}'. Only alphanumeric characters, spaces, and _-./@ are allowed."
83+
exit 1
84+
fi
85+
86+
# Validate that inputs.path contains only safe characters
87+
if [[ ! "${{ inputs.path }}" =~ ^[a-zA-Z0-9_\-\./]+$ ]]; then
88+
echo "::error::Invalid dependency path: '${{ inputs.path }}'. Only alphanumeric characters and _-./ are allowed."
89+
exit 1
90+
fi
91+
7592
# What we need to accomplish:
7693
# * update to the latest tag
7794
# * create a PR
@@ -90,6 +107,7 @@ jobs:
90107
# We do different approach on subsequent runs because otherwise we would spam users' mailboxes
91108
# with notifications about pushes to existing PRs. This way there is actually no push if not needed.
92109
update:
110+
needs: validate-inputs
93111
runs-on: ${{ inputs.runs-on }}
94112
# Map the job outputs to step outputs
95113
outputs:
@@ -102,6 +120,12 @@ jobs:
102120
defaults:
103121
run:
104122
shell: pwsh
123+
env:
124+
DEPENDENCY_NAME: ${{ inputs.name }}
125+
DEPENDENCY_PATH: ${{ inputs.path }}
126+
DEPENDENCY_PATTERN: ${{ inputs.pattern }}
127+
CHANGELOG_SECTION: ${{ inputs.changelog-section }}
128+
PR_STRATEGY: ${{ inputs.pr-strategy }}
105129
steps:
106130
- uses: actions/checkout@v4
107131
with:
@@ -121,18 +145,18 @@ jobs:
121145
122146
- name: Update to the latest version
123147
id: target
124-
run: ${{ runner.temp }}/ghwf/updater/scripts/update-dependency.ps1 -Path '${{ inputs.path }}' -Pattern '${{ inputs.pattern }}'
148+
run: ${{ runner.temp }}/ghwf/updater/scripts/update-dependency.ps1 -Path "$env:DEPENDENCY_PATH" -Pattern "$env:DEPENDENCY_PATTERN"
125149

126150
- name: Get the base repo info
127151
if: steps.target.outputs.latestTag != steps.target.outputs.originalTag
128152
id: root
129153
run: |
130154
$mainBranch = $(git remote show origin | Select-String "HEAD branch: (.*)").Matches[0].Groups[1].Value
131-
$prBranch = switch ('${{ inputs.pr-strategy }}')
155+
$prBranch = switch ($env:PR_STRATEGY)
132156
{
133-
'create' { 'deps/${{ inputs.path }}/${{ steps.target.outputs.latestTag }}' }
134-
'update' { 'deps/${{ inputs.path }}' }
135-
default { throw "Unkown PR strategy '${{ inputs.pr-strategy }}'." }
157+
'create' { "deps/$env:DEPENDENCY_PATH/${{ steps.target.outputs.latestTag }}" }
158+
'update' { "deps/$env:DEPENDENCY_PATH" }
159+
default { throw "Unkown PR strategy '$env:PR_STRATEGY'." }
136160
}
137161
"baseBranch=$mainBranch" | Tee-Object $env:GITHUB_OUTPUT -Append
138162
"prBranch=$prBranch" | Tee-Object $env:GITHUB_OUTPUT -Append
@@ -185,11 +209,11 @@ jobs:
185209
with:
186210
base: ${{ steps.root.outputs.baseBranch }}
187211
branch: ${{ steps.root.outputs.prBranch }}
188-
commit-message: 'chore: update ${{ inputs.path }} to ${{ steps.target.outputs.latestTag }}'
212+
commit-message: 'chore: update ${{ env.DEPENDENCY_PATH }} to ${{ steps.target.outputs.latestTag }}'
189213
author: 'GitHub <[email protected]>'
190-
title: 'chore(deps): update ${{ inputs.name }} to ${{ steps.target.outputs.latestTagNice }}'
214+
title: 'chore(deps): update ${{ env.DEPENDENCY_NAME }} to ${{ steps.target.outputs.latestTagNice }}'
191215
body: |
192-
Bumps ${{ inputs.path }} from ${{ steps.target.outputs.originalTag }} to ${{ steps.target.outputs.latestTag }}.
216+
Bumps ${{ env.DEPENDENCY_PATH }} from ${{ steps.target.outputs.originalTag }} to ${{ steps.target.outputs.latestTag }}.
193217
194218
Auto-generated by a [dependency updater](https://github.com/getsentry/github-workflows/blob/main/.github/workflows/updater.yml).
195219
${{ env.TARGET_CHANGELOG }}
@@ -223,19 +247,19 @@ jobs:
223247

224248
- name: 'After new PR: redo the update'
225249
if: ${{ ( steps.target.outputs.latestTag != steps.target.outputs.originalTag ) && ( steps.existing-pr.outputs.url == '') && ( steps.root.outputs.changed == 'false') }}
226-
run: ${{ runner.temp }}/ghwf/updater/scripts/update-dependency.ps1 -Path '${{ inputs.path }}' -Tag '${{ steps.target.outputs.latestTag }}'
250+
run: ${{ runner.temp }}/ghwf/updater/scripts/update-dependency.ps1 -Path "$env:DEPENDENCY_PATH" -Tag '${{ steps.target.outputs.latestTag }}'
227251

228252
- name: Update Changelog
229253
if: ${{ inputs.changelog-entry && ( steps.target.outputs.latestTag != steps.target.outputs.originalTag ) && ( steps.root.outputs.changed == 'false') }}
230254
run: |
231255
${{ runner.temp }}/ghwf/updater/scripts/update-changelog.ps1 `
232-
-Name '${{ inputs.name }}' `
256+
-Name "$env:DEPENDENCY_NAME" `
233257
-PR '${{ steps.pr.outputs.url }}' `
234258
-RepoUrl '${{ steps.target.outputs.url }}' `
235259
-MainBranch '${{ steps.target.outputs.mainBranch }}' `
236260
-OldTag '${{ steps.target.outputs.originalTag }}' `
237261
-NewTag '${{ steps.target.outputs.latestTag }}' `
238-
-Section '${{ inputs.changelog-section }}'
262+
-Section "$env:CHANGELOG_SECTION"
239263
240264
- run: git --no-pager diff
241265
if: ${{ ( steps.target.outputs.latestTag != steps.target.outputs.originalTag ) && ( steps.root.outputs.changed == 'false') }}
@@ -247,11 +271,11 @@ jobs:
247271
with:
248272
base: ${{ steps.root.outputs.baseBranch }}
249273
branch: ${{ steps.root.outputs.prBranch }}
250-
commit-message: 'chore: update ${{ inputs.path }} to ${{ steps.target.outputs.latestTag }}'
274+
commit-message: 'chore: update ${{ env.DEPENDENCY_PATH }} to ${{ steps.target.outputs.latestTag }}'
251275
author: 'GitHub <[email protected]>'
252-
title: 'chore(deps): update ${{ inputs.name }} to ${{ steps.target.outputs.latestTagNice }}'
276+
title: 'chore(deps): update ${{ env.DEPENDENCY_NAME }} to ${{ steps.target.outputs.latestTagNice }}'
253277
body: |
254-
Bumps ${{ inputs.path }} from ${{ steps.target.outputs.originalTag }} to ${{ steps.target.outputs.latestTag }}.
278+
Bumps ${{ env.DEPENDENCY_PATH }} from ${{ steps.target.outputs.originalTag }} to ${{ steps.target.outputs.latestTag }}.
255279
256280
Auto-generated by a [dependency updater](https://github.com/getsentry/github-workflows/blob/main/.github/workflows/updater.yml).
257281
${{ env.TARGET_CHANGELOG }}

0 commit comments

Comments
 (0)