Description of the issue
The actions/code-injection query doesn't flag an injectable workflow if the job has an if: condition that looks like an actor check, even when that check can never do anything for the event that triggers the workflow.
Repro (CodeQL CLI 2.26.3, codeql/actions-queries default suite):
name: repro
on:
issues:
types: [opened]
jobs:
j:
runs-on: ubuntu-latest
if: github.event.pull_request.user.login != 'some-bot[bot]'
steps:
- run: |
echo '${{ github.event.issue.title }}'
No alert is reported. Remove the if: line and actions/code-injection/critical fires.
The if: condition provides no protection here. The workflow only triggers on issues events, and github.event.pull_request doesn't exist in an issues payload, so the comparison is always true. Any user who opens an issue reaches the injectable run: step.
The query misses this because of how ActorIfCheck works. It uses a regex to look for actor fields like github.event.pull_request.user.login anywhere in the condition. If it finds one, the job counts as protected. It never checks whether that field actually exists for the event that triggers the workflow, so this always-true condition suppresses the alert.
I started digging into this after reading the Wiz write-up on the snowflakedb/snowflake-connector-net injection and wondering why the code-injection query never alerted on the vulnerable workflow. Running that workflow file through the current query locally confirmed the gate is what suppresses the alert:
| Variant |
Alert? |
Full workflow as committed (with its if: gate) |
no |
Same file, if: removed |
yes |
if: reduced to only the pull_request.user.login != '...' clause |
no |
When I searched for existing issues/PRs on this topic I found #22154, which fixed the same kind of problem for EnvironmentCheck. The PR description there even suggested reviewing whether other check types have this issue. ActorIfCheck (and possibly the other If-based checks) appears to.
Description of the issue
The
actions/code-injectionquery doesn't flag an injectable workflow if the job has anif:condition that looks like an actor check, even when that check can never do anything for the event that triggers the workflow.Repro (CodeQL CLI 2.26.3,
codeql/actions-queriesdefault suite):No alert is reported. Remove the
if:line andactions/code-injection/criticalfires.The
if:condition provides no protection here. The workflow only triggers onissuesevents, andgithub.event.pull_requestdoesn't exist in an issues payload, so the comparison is always true. Any user who opens an issue reaches the injectablerun:step.The query misses this because of how
ActorIfCheckworks. It uses a regex to look for actor fields likegithub.event.pull_request.user.loginanywhere in the condition. If it finds one, the job counts as protected. It never checks whether that field actually exists for the event that triggers the workflow, so this always-true condition suppresses the alert.I started digging into this after reading the Wiz write-up on the snowflakedb/snowflake-connector-net injection and wondering why the code-injection query never alerted on the vulnerable workflow. Running that workflow file through the current query locally confirmed the gate is what suppresses the alert:
if:gate)if:removedif:reduced to only thepull_request.user.login != '...'clauseWhen I searched for existing issues/PRs on this topic I found #22154, which fixed the same kind of problem for
EnvironmentCheck. The PR description there even suggested reviewing whether other check types have this issue.ActorIfCheck(and possibly the otherIf-based checks) appears to.