You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Daily static analysis scan of all agentic workflows using zizmor, poutine, and actionlint. Total findings decreased marginally by 1 versus the previous scan (8601 → 8600), though the composition shifted: zizmor findings dropped by 230 while actionlint findings grew by 229, reflecting new workflow additions and incremental shellcheck growth.
Affected: 47 workflows including audit-workflows, copilot-pr-nlp-analysis, copilot-session-insights, daily-code-metrics, daily-firewall-report, daily-news, issue-monster, poem-bot, scout, q, and 37 more
Description: $\{\{ github.event.* }} expressions directly interpolated into run: shell scripts, enabling shell command injection via crafted issue titles, comment bodies, or PR branch names
Impact: An attacker can execute arbitrary commands in the runner by creating an issue or comment with shell metacharacters
Description: bash scripts executed from checkout in workflows triggered by PRs — arbitrary code execution risk from untrusted contributors
Note: Lines are marked # poutine:ignore untrusted_checkout_exec but findings still surface
Fix Suggestion for Template Injection
Issue: template-injection — Code Injection via Template Expansion Severity: High Affected Workflows: 47 workflows (24 with High severity) Reference: (docs.zizmor.sh/redacted)
Prompt to Copilot Agent:
You are fixing a security vulnerability identified by zizmor in GitHub Actions workflows.
**Vulnerability**: template-injection — Code Injection via Template Expansion
**Rule**: template-injection
**Reference**: (docs.zizmor.sh/redacted)
**Severity**: High
**Current Issue**:
GitHub Actions $\{\{ expression }} template syntax is used directly inside run: shell scripts
with user-controlled values (e.g. github.event.issue.title, github.event.comment.body,
github.head_ref). An attacker can craft a malicious issue title or comment to inject
arbitrary shell commands.
**Required Fix**:
Replace all $\{\{ user_controlled_expression }} inside run: scripts with environment variables.
Move the value to the step's env: block and reference it as a shell variable $VAR_NAME.
Before (vulnerable):
- name: Process
run: |
echo "$\{\{ github.event.issue.title }}"
After (safe):
- name: Process
env:
ISSUE_TITLE: $\{\{ github.event.issue.title }}
run: |
echo "\$\{ISSUE_TITLE}"
Safe to keep inline (not user-controlled):
- $\{\{ github.run_id }} (numeric)
- $\{\{ github.sha }} (hex)
- $\{\{ runner.temp }} (path)
Must move to env: (user-controlled):
- github.event.issue.title / body / number
- github.event.comment.body
- github.event.pull_request.title / head.ref
- github.event.*.name fields
Please apply this fix to all affected workflow .md files.
Affected workflows (High severity): audit-workflows, copilot-pr-nlp-analysis,
copilot-session-insights, daily-code-metrics, daily-copilot-token-report,
daily-firewall-report, daily-integrity-analysis, daily-issues-report,
daily-multi-device-docs-tester, daily-news, daily-performance-summary,
daily-repo-chronicle, deep-report, docs-noob-tester, github-mcp-structural-analysis,
grumpy-reviewer, issue-arborist, issue-monster, issue-triage-agent, org-health-report,
plan, poem-bot, portfolio-analyst, pr-triage-agent, python-data-charts, q, refiner,
scout, smoke-agent-all-merged, smoke-agent-all-none, smoke-agent-public-approved,
smoke-agent-public-none, smoke-agent-scoped-approved, smoke-copilot, smoke-service-ports,
stale-repo-identifier, technical-doc-writer, unbloat-docs, weekly-blog-post-writer,
weekly-editors-health-check, weekly-issue-summary, weekly-safe-outputs-spec-review,
workflow-generator, discussion-task-miner, daily-doc-updater, contribution-check,
auto-triage-issues
All 179 workflows are flagged because secrets are referenced in jobs that do not use a named GitHub environment (environment:). This is a widespread structural pattern in the gh-aw harness. zizmor recommends using named environments to constrain secret access, but this would require significant harness-level changes.
Zizmor: unpinned-uses (High — 5 occurrences in daily-fact)
daily-fact uses github/gh-aw-actions/setup@v0 (a mutable tag). This should be pinned to a specific SHA for supply chain security.
Zizmor: github-env (High — 1 occurrence in dev-hawk)
dev-hawk writes untrusted data to $GITHUB_ENV, which can set environment variables for subsequent steps — potential environment injection vector.
Actionlint: expression undefined properties
runner.imageid — used in 10 workflows via qmd experimental feature
activation.outputs.activated — used in ace-editor
activation.outputs.artifact_prefix — used in smoke-claude
These likely reflect schema drift between the workflow compiler's output type definitions and actual field names.
Immediate — Fix template-injection (High): Apply the Copilot agent prompt above to the 24 High-severity workflows. This eliminates a real shell injection attack vector.
Short-term — Fix github-env in dev-hawk: Audit what is written to $GITHUB_ENV and sanitize or remove it.
Short-term — Pin daily-fact action: Replace @v0 with a specific commit SHA for github/gh-aw-actions/setup.
Long-term — Ecosystem identifier for Go proxy: Replace individual proxy.golang.org / sum.golang.org firewall domains with the go ecosystem identifier in issue-triage-agent.
Ongoing — SC2086 shellcheck: The harness uses bash \$\{RUNNER_TEMP}/... extensively with unquoted \$\{}. While low-risk (RUNNER_TEMP is system-controlled), quoting would clean up the noise.
Next Steps
Apply template-injection fix to all 47 affected workflows using the Copilot agent prompt above
Fix github-env write in dev-hawk
Pin daily-fact action reference to a SHA
Investigate and fix undefined expression properties (imageid, activated, artifact_prefix)
Review smoke-workflow-call untrusted_checkout_exec — determine if poutine:ignore suppression is appropriate
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
Analysis Summary
Daily static analysis scan of all agentic workflows using zizmor, poutine, and actionlint. Total findings decreased marginally by 1 versus the previous scan (8601 → 8600), though the composition shifted: zizmor findings dropped by 230 while actionlint findings grew by 229, reflecting new workflow additions and incremental shellcheck growth.
Findings by Tool
Clustered Findings by Tool and Type
Zizmor Security Findings
secrets-outside-envtemplate-injectionobfuscationunpinned-usesgithub-envartipackedsecrets-inheritPoutine Supply Chain Findings
untrusted_checkout_execpr_runs_on_self_hostedgithub_action_from_unverified_creator_usedunverified_script_execunpinnable_actionActionlint Linting Issues
shellcheck SC2086shellcheck SC2129permissionscopilot-requests: writeexpressionrunner-labelshellcheck SC2012Top Priority Issues
1. Template Injection (High Severity — 47 Workflows)
audit-workflows,copilot-pr-nlp-analysis,copilot-session-insights,daily-code-metrics,daily-firewall-report,daily-news,issue-monster,poem-bot,scout,q, and 37 more$\{\{ github.event.* }}expressions directly interpolated intorun:shell scripts, enabling shell command injection via crafted issue titles, comment bodies, or PR branch names2. Unknown Permission Scope
copilot-requests(74 Occurrences — ~41 Workflows)copilot-requests: writewhich is not a recognized GitHub Actions permission scope3. Expression Property Undefined (13 Occurrences — ~10 Workflows)
runner.imageid,activation.outputs.activated,activation.outputs.artifact_prefix4. Untrusted Checkout Exec — Poutine (6 Occurrences — 2 Workflows)
smoke-workflow-call,smoke-workflow-call-with-inputsbashscripts executed from checkout in workflows triggered by PRs — arbitrary code execution risk from untrusted contributors# poutine:ignore untrusted_checkout_execbut findings still surfaceFix Suggestion for Template Injection
Issue: template-injection — Code Injection via Template Expansion
Severity: High
Affected Workflows: 47 workflows (24 with High severity)
Reference: (docs.zizmor.sh/redacted)
Prompt to Copilot Agent:
All Findings Details by Category
Zizmor: secrets-outside-env (Medium — 3,627 occurrences)
All 179 workflows are flagged because secrets are referenced in jobs that do not use a named GitHub environment (
environment:). This is a widespread structural pattern in the gh-aw harness. zizmor recommends using named environments to constrain secret access, but this would require significant harness-level changes.Zizmor: unpinned-uses (High — 5 occurrences in daily-fact)
daily-factusesgithub/gh-aw-actions/setup@v0(a mutable tag). This should be pinned to a specific SHA for supply chain security.Zizmor: github-env (High — 1 occurrence in dev-hawk)
dev-hawkwrites untrusted data to$GITHUB_ENV, which can set environment variables for subsequent steps — potential environment injection vector.Actionlint: expression undefined properties
runner.imageid— used in 10 workflows viaqmdexperimental featureactivation.outputs.activated— used inace-editoractivation.outputs.artifact_prefix— used insmoke-claudeThese likely reflect schema drift between the workflow compiler's output type definitions and actual field names.
Poutine: github_action_from_unverified_creator_used (Note)
Third-party actions from unverified publishers:
actions-ecosystem/action-add-labels(smoke-codex)astral-sh/setup-uv(mcp-inspector, copilot-setup-steps, daily-copilot-token-report)gaurav-nelson/github-action-markdown-link-check(link-check)super-linter/super-linter(super-linter)All are pinned to commit SHAs, which mitigates the risk.
Historical Trends
Changes vs. yesterday (2026-04-01):
secrets-outside-envdecreased from 3,861 → 3,627)New Issues (vs. 2026-04-01)
Resolved Issues
Recommendations
github-envin dev-hawk: Audit what is written to$GITHUB_ENVand sanitize or remove it.daily-factaction: Replace@v0with a specific commit SHA forgithub/gh-aw-actions/setup.runner.imageid(qmd experimental feature),activation.outputs.activated(ace-editor schema), andactivation.outputs.artifact_prefix(smoke-claude).proxy.golang.org/sum.golang.orgfirewall domains with thegoecosystem identifier inissue-triage-agent.bash \$\{RUNNER_TEMP}/...extensively with unquoted\$\{}. While low-risk (RUNNER_TEMP is system-controlled), quoting would clean up the noise.Next Steps
github-envwrite indev-hawkdaily-factaction reference to a SHAsmoke-workflow-calluntrusted_checkout_exec — determine ifpoutine:ignoresuppression is appropriateReferences:
Beta Was this translation helpful? Give feedback.
All reactions