Repository navigation
Pass ref and tag names to the shell through the environment - #164
Merged
Merged
Conversation
publish.yml's gh release steps, fusion-docs.yml's asset upload and code-check.yml's base-commit logic interpolated tag and branch names straight into their scripts. Ref names may contain $(), backticks and ';', so a crafted tag or branch would run as shell code -- in publish's case, in the job that holds id-token: write. Pass them in environment variables and quote them, as code-check already does for HEAD_REF. Found by review bots on sqlalchemy-singlestoredb #23, which had copied the publish steps from here. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kesmit13
requested review from
bharathts07,
mgiannakopoulos,
pmishchenko-ua and
volodymyr-memsql
as code owners
November 13, 2026 15:28
The create_test_cluster.py calls in publish.yml and smoke-test.yml, and publish.yml's shutdown curl, interpolated CLUSTER_PASSWORD and CLUSTER_API_KEY into their commands, so a quote, $ or backtick in either would break or alter the command. Pass them in environment variables, as the drop steps and smoke-test.yml's shutdown already do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues are reported for the workflow shell-safety changes.
No open issues 🎉
What changed in this PR
Hardens GitHub Actions workflows by passing ref names, release tags, and cluster credentials through environment variables instead of interpolating them directly into shell scripts. This prevents their contents from being interpreted as shell code while preserving intended workflow behavior.
Changes:
- Uses quoted environment variables for branch comparisons and release creation/uploads.
- Moves cluster credentials into step-level environment variables for provisioning and shutdown.
- Adds comments explaining the shell-safety rationale.
| File | Description |
|---|---|
.github/workflows/smoke-test.yml |
Passes cluster provisioning credentials through environment variables. |
.github/workflows/publish.yml |
Safely passes release tags and cluster credentials to shell commands. |
.github/workflows/fusion-docs.yml |
Uses a quoted tag environment variable for documentation asset uploads. |
.github/workflows/code-check.yml |
Uses environment variables for event and branch comparisons. |
Review effort: Balanced
This branch was previously deployed
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.
Four workflow steps interpolate tag or branch names straight into
run:scripts:publish.yml: "Create GitHub Release" (github.ref_name) and "Upload release assets" (github.event.release.tag_name)fusion-docs.yml: "Upload release asset" (github.event.release.tag_name)code-check.yml: "Check for changes in monitored directories" (github.ref_name,github.event.pull_request.base.ref)Git ref names may contain
$(), backticks and;, so a crafted tag or branch name would run as shell code. Inpublish.ymlthat code runs in the job that holdsid-token: write. Creating such a ref needs write access to the repo, so this is hardening rather than an open hole, but the fix is mechanical: pass each name in an environment variable and quote it.code-check.ymlalready does this forHEAD_REF. Behavior is otherwise unchanged.The same commit series also moves
CLUSTER_PASSWORDandCLUSTER_API_KEYout of three commands and intoenv. The commands are thecreate_test_cluster.pycalls inpublish.ymlandsmoke-test.yml, andpublish.yml's shutdowncurl. Those values aren't attacker-controlled, but the shell interpreted them, so a quote,$or backtick would have broken or altered the command. The drop steps andsmoke-test.yml's shutdown already pass them this way.CIBW_ENVIRONMENTis left as is; its comment already requires an alphanumeric password.CodeRabbit and Cursor Bugbot flagged this on sqlalchemy-singlestoredb#23, which had copied the publish steps from here.
Testing
v1.2.1-test2), which created the prerelease with its assets.publish.yml, so its own run exercises the changedsetup-databaseandshutdown-databasesteps against a real cluster.run:script. The only other one, insmoke-test.yml, is inside anif:expression, which is not passed through a shell.🤖 Generated with Claude Code
Note
Low Risk
Workflow-only quoting/env changes with no application logic impact; reduces shell-injection risk in release and cluster jobs.
Overview
Hardens CI workflows by stopping direct interpolation of branch names, release tags, and API secrets into
run:shell scripts. Values now come through quoted environment variables (BASE_REF,REF_NAME,TAG,CLUSTER_PASSWORD,CLUSTER_API_KEY, etc.) so malicious or unusual ref/tag characters ($(), backticks,;) cannot execute as shell code.Touched workflows:
code-check.yml(PR base vs push comparison),fusion-docs.ymlandpublish.yml(release create/upload),publish.yml/smoke-test.yml(test cluster provision and teardown). Runtime behavior is unchanged; this is defensive hardening for jobs that already hold sensitive permissions or secrets.Reviewed by Cursor Bugbot for commit 5e39a5b. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit