fix(ci): prevent shell injection via PR title in custom-version workflows#349
Merged
Merged
Conversation
…lows
The Extract version step interpolated `github.event.pull_request.title`
directly into the bash script via `${{ ... }}`, which expands before the
shell parses it. A PR title containing `"` plus `&&` or `$(...)` could
break out of the string literal and execute arbitrary commands on the
runner, including writing to `$GITHUB_ENV` to poison later steps that
have access to UIPATH_* secrets.
Moves the title into an env var (which the shell parser treats as data,
never code) and rewrites the affected steps in PowerShell Core for
consistency with the already-secured publish-dev.yml.
Tracking: PRODEV-239
|
There was a problem hiding this comment.
Pull request overview
This PR hardens the lint-custom-version.yml and test-custom-version.yml GitHub Actions workflows against shell injection by ensuring the PR title is treated strictly as data when extracting the custom x.y.z.devNNN UiPath version.
Changes:
- Pass the PR title into the extraction step via
env:instead of interpolating it directly into arun:script. - Switch the affected steps from
bashtopwshand implement version extraction using .NET regex matching. - Update the pyproject modification logic in PowerShell while preserving the same version regex constraint and ensuring
[tool.uv.sources]includesuipath = { index = "testpypi" }.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| .github/workflows/test-custom-version.yml | Prevents PR-title-driven shell injection and updates pyproject editing to PowerShell across Ubuntu/Windows matrix runs. |
| .github/workflows/lint-custom-version.yml | Applies the same PR-title handling hardening and PowerShell-based pyproject update in the lint workflow. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
radu-mocanu
approved these changes
May 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
lint-custom-version.ymlandtest-custom-version.ymlinterpolatedgithub.event.pull_request.titledirectly into the bashrun:block via${{ ... }}. Because that interpolation happens before the shell parses the script, a PR title containing"plus&&/$(...)could break out of the string literal and execute arbitrary commands on the runner — including writing to$GITHUB_ENVto poison later steps.publish-dev.yml, flagged in the issue comments.test-custom-version.ymlis higher: a later step runsuv run pytestwithUIPATH_URL/UIPATH_CLIENT_ID/UIPATH_CLIENT_SECRETin env, so a hijacked early step could drop a malicious conftest/build hook to exfiltrate them.Fix
env:block instead of${{ }}interpolation — the shell parser only ever sees the env-var reference, never the attacker-controlled value as code.bashsteps to PowerShell Core (pwsh) for consistency.[0-9]+\.[0-9]+\.[0-9]+\.dev[0-9]+) is preserved, so theModify pyproject.tomlstep's input is still safe even before reachingSet-Content.POC the fix blocks
PR title:
Before: writes attacker-controlled env vars for later steps.
After: the title is read as data from
$env:PR_TITLE, never executed.Test plan
test-core-dev-versionlabel, a valid title (e.g.bump uipath to 2.0.65.dev1004030443), and a change underpackages/**— Extract version step should succeed.Modify pyproject.tomlcorrectly inserts/preserves[tool.uv.sources]anduipath = { index = "testpypi" }for each detected package.Tracking: PRODEV-239