π¨ Runner-Guard Security Finding
Rule: RGS-008 β Secret Directly Interpolated in run Block
Severity: High
File: .github/workflows/ci.yml
Line: 776
Description
A ${{ secrets.* }} expression or ${{ github.token }} appears directly inside a run: block's shell script rather than being passed via the env: mapping.
When secrets are interpolated directly into run: blocks using ${{ }} expressions, they are literally pasted into the shell script as plain text before execution.
Impact
This creates multiple risks:
- Log exposure: The secret value becomes part of the shell script text, potentially visible in error messages, debug logs, or process listings
- Shell injection: If the secret value contains shell metacharacters (quotes, backticks, dollar signs, semicolons), it can break the shell script syntax or cause unintended command execution
- Side-channel exposure: The secret is exposed to shell history and
/proc filesystem
- Expression injection amplification: Any expression injection vulnerability in the same
run: block gains direct access to the secret value
GitHub's log masking only redacts known secret values from output, but cannot prevent secrets from being captured via side channels when they are embedded in the script source.
Remediation
Pass secrets via the env: mapping instead of direct interpolation:
Before (vulnerable):
- name: Deploy
run: |
curl -H "Authorization: Bearer ${{ secrets.API_TOKEN }}" (api.example.com/redacted)
After (safe):
- name: Deploy
env:
API_TOKEN: ${{ secrets.API_TOKEN }}
run: |
curl -H "Authorization: Bearer ${API_TOKEN}" (api.example.com/redacted)
This ensures the secret is passed as an environment variable and never directly embedded in the shell script text.
Detected by runner-guard v2.6.0 β CI/CD source-to-sink vulnerability scanner
Workflow run: https://github.com/github/gh-aw/actions/runs/25244792701
Generated by Static Analysis Report Β· β 581K Β· β·
π¨ Runner-Guard Security Finding
Rule: RGS-008 β Secret Directly Interpolated in run Block
Severity: High
File:
.github/workflows/ci.ymlLine: 776
Description
A
${{ secrets.* }}expression or${{ github.token }}appears directly inside arun:block's shell script rather than being passed via theenv:mapping.When secrets are interpolated directly into
run:blocks using${{ }}expressions, they are literally pasted into the shell script as plain text before execution.Impact
This creates multiple risks:
/procfilesystemrun:block gains direct access to the secret valueGitHub's log masking only redacts known secret values from output, but cannot prevent secrets from being captured via side channels when they are embedded in the script source.
Remediation
Pass secrets via the
env:mapping instead of direct interpolation:Before (vulnerable):
After (safe):
This ensures the secret is passed as an environment variable and never directly embedded in the shell script text.
Detected by runner-guard v2.6.0 β CI/CD source-to-sink vulnerability scanner
Workflow run: https://github.com/github/gh-aw/actions/runs/25244792701