Skip to content

fix: complete script injection hardening across all actions#152

Merged
vaind merged 4 commits into
mainfrom
fix/complete-script-injection-hardening
May 11, 2026
Merged

fix: complete script injection hardening across all actions#152
vaind merged 4 commits into
mainfrom
fix/complete-script-injection-hardening

Conversation

@vaind
Copy link
Copy Markdown
Contributor

@vaind vaind commented Mar 24, 2026

Summary

Follow-up to #150 which moved user inputs to env vars but left step outputs (steps.*.outputs.*) directly interpolated in run: blocks. An attacker controlling e.g. git tags in a dependency repo could still inject arbitrary commands.

  • updater/action.yml: Move all remaining step outputs (tags, URLs, branch names) to env: blocks; replace PowerShell double-quote string interpolation with concatenation throughout to eliminate any possibility of subexpression evaluation
  • sentry-cli/integration-test/action.yml: Same double-quote to concatenation fix
  • danger/action.yml: Move Docker image version tag from direct ${{ }} interpolation to env var with semver validation

After this change, the only ${{ }} expressions remaining in run: blocks are GitHub-controlled values (github.action_path, github.repository, github.repository_owner).

Refs: VULN-1100

Test plan

  • Verify updater action still works (dependency name/path validation, PR creation, changelog update)
  • Verify danger action still runs (container setup with version from properties file)
  • Verify sentry-cli integration tests still pass

🤖 Generated with Claude Code

PR #150 moved user inputs to env vars but left step outputs
(`steps.*.outputs.*`) directly interpolated in `run:` blocks —
an attacker controlling e.g. git tags in a dependency repo could
still inject arbitrary commands.

Additionally, switch all PowerShell run blocks from double-quote
string interpolation (`"$env:VAR"`) to string concatenation
(`'prefix' + $env:VAR`) to eliminate any possibility of
subexpression evaluation.

Changes:
- updater/action.yml: move all remaining step outputs (tags, URLs,
  branch names) to env vars; replace double-quote interpolation
  with concatenation throughout
- sentry-cli/integration-test/action.yml: same concatenation fix
- danger/action.yml: move docker image version from direct
  interpolation to env var with semver validation

Refs: VULN-1100

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@linear-code
Copy link
Copy Markdown

linear-code Bot commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Hardens composite GitHub Actions against script injection by removing direct interpolation of step outputs into run: blocks and by avoiding PowerShell double-quoted interpolation patterns.

Changes:

  • updater/action.yml: Move step outputs into env: and switch to PowerShell string concatenation for output/log construction.
  • sentry-cli/integration-test/action.yml: Replace PowerShell double-quoted interpolation with concatenation.
  • danger/action.yml: Pass Docker image version via env with a semver format validation before use.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
updater/action.yml Reworks multiple pwsh steps to avoid ${{ steps.* }} in run: and removes double-quoted interpolation in favor of concatenation.
sentry-cli/integration-test/action.yml Updates module import and Pester invocation to avoid double-quoted interpolation.
danger/action.yml Uses DANGER_VERSION env var for the Docker image tag and validates it as semver to prevent injection.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread updater/action.yml Outdated
Comment thread updater/action.yml Outdated
Comment thread updater/action.yml
vaind and others added 3 commits March 24, 2026 23:42
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
PR branches derived from CMake dependency paths can contain '#', which
the previous query-string concatenation would treat as a URL fragment
delimiter and truncate. Switch to `gh api -X GET -f` so gh URL-encodes
the values, ensuring existing PRs are still matched when the branch
name contains special characters.

Also add the changelog entry for this PR so the advisory danger check
passes.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Comment thread updater/action.yml
# Validate that inputs.name contains only safe characters
if ("$env:DEPENDENCY_NAME" -notmatch '^[a-zA-Z0-9_\./@\s-]+$') {
Write-Output "::error::Invalid dependency name: '$env:DEPENDENCY_NAME'. Only alphanumeric characters, spaces, and _-./@ are allowed."
if ($env:DEPENDENCY_NAME -notmatch '^[a-zA-Z0-9_\./@\s-]+$') {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope for this PR — regex was added in #150, and \s here does not create an injection vector since the value is consumed via env vars / script parameters, not shell interpolation. The message/regex mismatch is worth a follow-up.

Comment thread updater/action.yml
# Validate that inputs.post-update-script contains only safe characters
if ("$env:POST_UPDATE_SCRIPT" -notmatch '^[a-zA-Z0-9_\./#\s-]+$') {
Write-Output "::error::Invalid post-update-script path: '$env:POST_UPDATE_SCRIPT'. Only alphanumeric characters, spaces, and _-./# are allowed."
if ($env:POST_UPDATE_SCRIPT -notmatch '^[a-zA-Z0-9_\./#\s-]+$') {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the DEPENDENCY_NAME case above — pre-existing from #150, not a security concern for this PR (value flows through env vars to PowerShell, no shell interpolation). Candidate for a small follow-up.

Comment thread updater/action.yml
else
{
throw "Unexpected number of PRs matched ($($urls.Length)): $urls"
throw ('Unexpected number of PRs matched (' + $urls.Length + '): ' + $urls)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

False positive — PowerShell coerces array → string via $OFS (default space). "msg: " + @("a","b") yields msg: a b, not System.Object[]. Verified locally. This is the second time this exact comment has been raised on the PR.

@vaind vaind requested a review from jpnurmi May 11, 2026 11:53
@vaind vaind merged commit 24be696 into main May 11, 2026
28 checks passed
@vaind vaind deleted the fix/complete-script-injection-hardening branch May 12, 2026 08:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants