Skip to content

fix(gha): run-shell-injection flags the truthiness-check shape on bare inputs - #4020

Open
munzzyy wants to merge 1 commit into
semgrep:developfrom
munzzyy:fix/run-shell-injection-inputs-truthiness
Open

fix(gha): run-shell-injection flags the truthiness-check shape on bare inputs#4020
munzzyy wants to merge 1 commit into
semgrep:developfrom
munzzyy:fix/run-shell-injection-inputs-truthiness

Conversation

@munzzyy

@munzzyy munzzyy commented Jul 27, 2026

Copy link
Copy Markdown

The run-shell-injection rule exempts the truthiness-check shape ${{ X && 'literal' }} from every dangerous source, since X is only evaluated for truthiness and never interpolated into the shell. There are 35 sources in the pattern-either list and 34 matching pattern-not exemptions. The one source that never got its exemption is inputs.

So ${{ inputs.foo && 'yes' }} still gets flagged, even though it's the exact same safe shape as ${{ github.head_ref && 'yes' }} a few lines up, which is correctly exempted.

Added the missing pattern-not: ${{ ... inputs ... && ... }} so inputs matches the other 34, and an ok: test case for it. A bare ${{ inputs.foo }} interpolation still fires, so this only drops the false positive on the truthiness shape, not any real detection.

Verification

I checked the rule structure directly: the pattern-either list has 35 sources, the truthiness pattern-not list has 34, and inputs is the only source with no matching entry. The added pattern mirrors the existing siblings exactly (${{ ... <source> ... && ... }}).

Added a paired ok: case in run-shell-injection.test.yaml (echo "${{ inputs.message_to_print && 'yes' }}"), alongside the existing ruleid: case for the bare interpolation, which stays flagged.

…e inputs

Every dangerous source in this rule has a pattern-not exempting the
${{ X && 'literal' }} shape, where X is only checked for truthiness and
never interpolated. There are 35 such sources and 34 of those exemptions;
inputs is the one that never got it. So ${{ inputs.foo && 'yes' }} is
still flagged even though it's the same safe shape as
${{ github.head_ref && 'yes' }} right next to it.

Added the missing pattern-not plus an ok: test case. A bare
${{ inputs.foo }} interpolation still fires, as it should.

Signed-off-by: Cole Munz <colemunz@gmail.com>
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