Skip to content

fix: push_code_samples_only handling, various injection preventions - #309

Open
bflad wants to merge 1 commit into
mainfrom
chore/actionlint-workflow-fixes
Open

fix: push_code_samples_only handling, various injection preventions#309
bflad wants to merge 1 commit into
mainfrom
chore/actionlint-workflow-fixes

Conversation

@bflad

@bflad bflad commented Feb 25, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds a new actionlint CI job to lint all workflow files on every push/PR
  • Fixes five script injection vulnerabilities where GitHub Actions context expressions were interpolated directly into run: scripts
  • Resolves all shellcheck violations surfaced by actionlint (SC2086 quoting, SC2035 glob safety, SC2059 printf format strings)
  • Fixes two workflow input bugs in workflow-executor.yaml (push_code_samples typo, dead output_tests reference)

actionlint job (test.yaml)

A new actionlint job runs on every push/PR to lint all workflow
files for shellcheck violations, script injection risks, and
undefined inputs. The linter is installed via go install github.com/rhysd/actionlint/cmd/actionlint@v1.7.11 per the
tool's recommended CI setup. Uses go-version-file: go.mod for
toolchain consistency and declares permissions: contents: read
per least-privilege hygiene.

Script injection fixes (workflow-executor.yaml, sdk-test.yaml)

GitHub Actions expressions in run: scripts are interpolated
before the shell parses the script, making them injection vectors.
Five values were moved from inline interpolation to step-level
env: variables so the shell sees them as safe environment
variable references rather than literal text:

  • github.event.pull_request.body$PR_BODY (attacker-controlled: PR body content)
  • github.event.head_commit.message$HEAD_COMMIT_MESSAGE (attacker-controlled: commit message content)
  • github.event.label.name$LABEL_NAME and github.event.action$EVENT_ACTION (label name is set by anyone with label-apply access; action is low-risk but fixed for consistency)
  • inputs.env_vars$ENV_VARS (workflow_call input; requires caller control, fixed for consistency)

Shell quoting and glob fixes (SC2086, SC2035, SC2059)

  • Unquoted $GITHUB_OUTPUT and $GITHUB_ENV redirections quoted throughout to prevent word splitting (SC2086)
  • Unquoted $TARGET and $BINARY_PATH in bun build commands quoted (SC2086)
  • *.nupkg./*.nupkg to prevent glob matching filenames starting with - being treated as flags (SC2035)
  • *.gemspec / *.gem./*.gemspec / ./*.gem (SC2035)
  • printf "...${VAR}..."printf '...' "${VAR}" to prevent the variable from being interpreted as a format string (SC2059)

Workflow input fixes (workflow-executor.yaml)

  • inputs.push_code_samplesinputs.push_code_samples_only: the workflow input was always named push_code_samples_only; the wrong name silently evaluated to empty string, so the option was never passed through
  • inputs.output_tests removed: this action input exists but was never wired as a workflow_call input, so the reference was always empty; removed to eliminate dead configuration

Test plan

  • Verify the new actionlint CI job passes on this PR
  • Verify the existing build CI job passes on this PR
  • Confirm actionlint runs cleanly locally: actionlint -color

🤖 Generated with Claude Code

@bflad
bflad requested a review from a team as a code owner February 25, 2026 09:32
@bflad bflad changed the title chore: add actionlint, fix workflow injection and shell issues fix: push_code_samples_only handling, various injection preventions Feb 25, 2026
@danielkov

Copy link
Copy Markdown
Contributor

./scipts/update-refs.sh? You'll also need to update that to set the env value.

Adds actionlint to the CI test matrix and resolves all issues it
surfaces, plus a few that were independently identified.

## actionlint job (test.yaml)

A new `actionlint` job runs on every push/PR to lint all workflow
files for shellcheck violations, script injection risks, and
undefined inputs. The linter is installed via `go install
github.com/rhysd/actionlint/cmd/actionlint@v1.7.11` per the
tool's recommended CI setup. Uses `go-version-file: go.mod` for
toolchain consistency and declares `permissions: contents: read`
per least-privilege hygiene.

## Script injection fixes (workflow-executor.yaml, sdk-test.yaml)

GitHub Actions expressions in `run:` scripts are interpolated
before the shell parses the script, making them injection vectors.
Five values were moved from inline interpolation to step-level
`env:` variables so the shell sees them as safe environment
variable references rather than literal text:

- `github.event.pull_request.body` → `$PR_BODY` (attacker-
  controlled: PR body content)
- `github.event.head_commit.message` → `$HEAD_COMMIT_MESSAGE`
  (attacker-controlled: commit message content)
- `github.event.label.name` → `$LABEL_NAME` and
  `github.event.action` → `$EVENT_ACTION` (label name is set by
  anyone with label-apply access; action is low-risk but fixed for
  consistency)
- `inputs.env_vars` → `$ENV_VARS` (workflow_call input; requires
  caller control, fixed for consistency)

## Shell quoting and glob fixes (SC2086, SC2035, SC2059)

- Unquoted `$GITHUB_OUTPUT` and `$GITHUB_ENV` redirections quoted
  throughout to prevent word splitting (SC2086)
- Unquoted `$TARGET` and `$BINARY_PATH` in bun build commands
  quoted (SC2086)
- `*.nupkg` → `./*.nupkg` to prevent glob matching filenames
  starting with `-` being treated as flags (SC2035)
- `*.gemspec` / `*.gem` → `./*.gemspec` / `./*.gem` (SC2035)
- `printf "...${VAR}..."` → `printf '...' "${VAR}"` to prevent
  the variable from being interpreted as a format string (SC2059)

## Workflow input fixes (workflow-executor.yaml)

- `inputs.push_code_samples` → `inputs.push_code_samples_only`:
  the workflow input was always named `push_code_samples_only`; the
  wrong name silently evaluated to empty string, so the option was
  never passed through
- `inputs.output_tests` removed: this action input exists but was
  never wired as a workflow_call input, so the reference was always
  empty; removed to eliminate dead configuration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@bflad
bflad force-pushed the chore/actionlint-workflow-fixes branch from 8c8196b to d4d9092 Compare February 25, 2026 11:53
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