Skip to content

fix(security): pipe action inputs through env vars (HIGH; shell injection)#3

Merged
mikemolinet merged 1 commit into
mainfrom
fix/shell-injection-via-env-vars
May 6, 2026
Merged

fix(security): pipe action inputs through env vars (HIGH; shell injection)#3
mikemolinet merged 1 commit into
mainfrom
fix/shell-injection-via-env-vars

Conversation

@mikemolinet
Copy link
Copy Markdown
Collaborator

Summary

Closes the HIGH shell-injection finding from cueapi-secondary's cross-agent review on PR #2. Pre-existing on main; filing as a standalone follow-up so the fix can ship independently of PR #2's review cadence.

The vulnerability

The current `action.yml` interpolates inputs directly into the bash script:

```yaml
[ -n "${{ inputs.payload }}" ] && cmd+=(--payload "${{ inputs.payload }}")
[ -n "${{ inputs.cue-id }}" ] && cmd+=("${{ inputs.cue-id }}")
```

GitHub Actions documents this as a classic injection vector. A workflow caller passing `payload: '"; rm -rf /; #'` (or any number of variations) gets arbitrary shell execution at the runner.

The worst case is the `command` interpolation in the case-statement value at line 90 — a malicious value like `create) ; rm -rf / ; #` could escape the case construct entirely and execute attacker-controlled commands before the case dispatcher even sees the input.

14 inputs were vulnerable: `command`, `name`, `cron`, `at`, `url`, `method`, `timezone`, `payload`, `description`, `worker`, `cue-id`, `status`, `limit`, `cli-version`. Every caller of `cueapi/cueapi-action@v1` is affected today.

The fix

Pipe every caller-supplied input through env vars in the step's `env:` block, then reference each as `$VAR_NAME` in the script. Bash quotes env-var expansion automatically, so `"$NAME"` is safe regardless of caller input.

This is the documented standard pattern.

```yaml
env:
COMMAND: ${{ inputs.command }}
NAME: ${{ inputs.name }}

...

run: |
set -euo pipefail
cmd=(cueapi "$COMMAND")
case "$COMMAND" in
create)
[ -n "$NAME" ] && cmd+=(--name "$NAME")
# ...
```

A comment block above the `env:` section flags the pattern for future contributors so the vulnerability isn't silently re-introduced when adding new inputs.

Coordination with PR #2

PR #2 (`feat: expose cueapi 0.2.0 fire + executions subgroup commands`) adds 16 new input references on the same vulnerable pattern. When this PR lands first, PR #2 will need a small rebase to follow the env-var pattern for its new inputs — straightforward mechanical change. Filing standalone keeps this fix on its own review track, so the hosted users on `@v1` get the fix even if PR #2 stays in Govind's review queue for a while.

Test plan

  • `python3 -c "import yaml; yaml.safe_load(open('action.yml'))"` — YAML valid
  • No behavior change for legitimate callers — same env-var expansion semantics, same `cmd=(...)` array assembly, same `cueapi` invocation
  • No new dependencies, no new runtime cost (env vars are already standard YAML composite-action plumbing)

Cross-references

🤖 Generated with Claude Code

…tion)

Per the GitHub Actions security guide, interpolating
`${{ inputs.X }}` directly into a `run:` shell script is a
documented injection vector — a workflow caller passing
e.g. `name: '"; rm -rf /; #'` gets arbitrary shell
execution at the runner.

The pre-existing pattern in `action.yml` was vulnerable on
every input: `command`, `name`, `cron`, `at`, `url`,
`method`, `timezone`, `payload`, `description`, `worker`,
`cue-id`, `status`, `limit`, and `cli-version` — 14 inputs,
all interpolated directly. The `command` interpolation in
the case-statement value was the worst case (a malicious
value like `create) ; rm -rf / ; #` could escape the case
construct entirely).

Fix: declare every caller-supplied input in the step's
`env:` block, reference each in the script as `$VAR_NAME`.
Bash quotes env-var expansion automatically, so `"$NAME"`
is safe regardless of caller input.

This is the same pattern documented at
https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable

Surfaced in cueapi-secondary's earlier review on PR #2
(2026-05-04 cross-agent review). Filing as a standalone
follow-up so the fix can ship independently of PR #2's
review cadence — the issue exists on main today, every
caller of `cueapi/cueapi-action@v1` is affected.

PR #2 (when it merges) will need to follow the same env-var
pattern for its 16 new input references; the comment block
above the env: section flags this for the maintainer.

No behavior change for legitimate callers — same env-var
expansion, same `cmd=(...)` array assembly, same
invocation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mikemolinet mikemolinet merged commit 25d5b0d into main May 6, 2026
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