Appearance
Why It Matters
Directly interpolating untrusted expression data into a shell run: step can turn workflow inputs or event data into shell syntax. The risk depends on how the value is consumed, which is why this rule stays preview even though the trigger is structural.
What Triggers
SEC325 applies to semantically confirmed GitHub Actions workflow YAML and triggers when:
- a
run:command directly embeds untrusted expression data such as${{ inputs.* }}or event payload values - and the expression is used inline in the shell command rather than first being assigned into a safer indirection path
Example that triggers:
yaml
- run: echo ${{ inputs.version }}Example that stays clean:
yaml
- run: VERSION=${{ inputs.version }}False Positives
This rule stays Preview because shell safety depends on how the interpolated value is ultimately consumed. The signal is still useful because direct inline interpolation is a high-risk composition pattern in CI.
Remediation
Avoid interpolating untrusted expression data directly inside run: commands. Route the value through validated environment handling or a safer non-shell boundary first.