Skip to content

Keep release tag names out of shell source - #473

Merged
metcalfc merged 2 commits into
mainfrom
security/fix-release-tag-shell-injection
Aug 26, 2026
Merged

metcalfc merged 2 commits into
mainfrom
security/fix-release-tag-shell-injection

Conversation

@metcalfc

Copy link
Copy Markdown
Owner

Summary

  • pass the release tag name to Bash through an environment variable
  • quote the derived major-version tag in both Git commands
  • add a regression test for the workflow's shell boundary

Security invariant

A matching tag name is data, never shell source. Existing major-version extraction remains compatible with the repository's current tag formats.

Verification

  • npm test — 29/29
  • npm run lint
  • npm run format-check
  • actionlint .github/workflows/release.yml
  • shell payload smoke tests for command substitution and backticks

metcalfc and others added 2 commits August 25, 2026 19:15
The major-tag step declared GITHUB_TOKEN: secrets.WORKFLOW_TOKEN, but git
never reads that variable. The push authenticates with the http.extraheader
credential actions/checkout persists, which is the default GITHUB_TOKEN, and
`refs/tags/v4` having no release proves it: a PAT-authored push would have
re-triggered create-release on the v4 tag. Record why the inertness is
load-bearing rather than leaving a line that reads like an oversight.

Also bound the guard test's step slice at the next step. Reading to
end-of-file only holds while the major-tag step is last in the file.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015EmepbnR2nSdk8q8DBsrsD
@metcalfc
metcalfc merged commit c2ec39e into main Aug 26, 2026
6 checks passed
@metcalfc
metcalfc deleted the security/fix-release-tag-shell-injection branch August 26, 2026 04:01
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.

1 participant