Repository navigation
[static-analysis] Report - 2026-10-19 #70164
Description
🔍 Static Analysis Report - 2026-10-19
Analysis Summary
- Tools Used: zizmor, poutine, actionlint, runner-guard, syft, grype, yamllint, shellcheck
- Total Findings: 20,528 (+51 / +0.25% vs 2026-10-18)
- Workflows Scanned: 345 (+1)
- Workflows Affected: 345 (every workflow has at least one zizmor low/info finding)
Findings by Tool
| Tool | Total | Critical | High | Medium | Low |
|---|---|---|---|---|---|
| zizmor (security) | 17,773 | 0 | 2 | 12,650 | 5,073 (+48 informational) |
| poutine (supply chain) | 30 | 0 | 0 | 1 | 0 (+29 informational) |
| actionlint (linting) | 134 | - | - | - | - |
| runner-guard (taint analysis) | 17 raw / 9 unique | 0 | 4 | 13 | 0 |
| syft (SBOM inventory) | 3,944 packages / 12 images | - | - | - | - |
| grype (container CVEs) | 2,570 | 50 | 619 | 802 | 151 (+866 negligible, 82 unknown) |
| yamllint (yaml linting) | 0 | - | - | - | - |
| shellcheck (shell linting) | 4 | - | - | - | - |
Clustered Findings by Tool and Type
Zizmor Security Findings
| Issue Type | Severity | Count | Affected Workflows |
|---|---|---|---|
| secrets-outside-env | Medium | 12,573 | 340 |
| self-repository | Low | 2,384 | 345 |
| undocumented-permissions | Low | 2,103 | 345 |
| adhoc-packages | Low | 559 | 293 |
| artipacked | Medium | 76 | 73 |
| template-injection | Informational | 47 | 42 |
| obfuscation | Low | 27 | 27 |
| unpinned-images | High | 1 | smoke-service-ports.lock.yml |
| bot-conditions | High | 1 | squad.lock.yml |
| secrets-inherit | Medium | 1 | windows-grower.lock.yml |
| superfluous-actions | Informational | 1 | smoke-codex.lock.yml |
Poutine Supply Chain Findings
| Issue Type | Severity | Count | Affected Workflows |
|---|---|---|---|
| github_action_from_unverified_creator_used | Informational | 29 | 29 (mostly astral-sh/setup-uv, see detail) |
| pr_runs_on_self_hosted | Medium | 1 | smoke-copilot-arm.lock.yml (likely false positive — ubuntu-24.04-arm is a GitHub-hosted ARM runner, not self-hosted) |
Actionlint Linting Issues
| Issue Type | Count | Affected Workflows |
|---|---|---|
| expression | 132 | 34 |
| shellcheck | 2 | 1 (sergo.lock.yml) |
All 132 expression errors are the same root cause: generated conclusion-job expressions reference needs.<job>.outputs.{report_incomplete, noop, missing_tool} properties that don't exist on the actual needs context object type (66× missing_tool, 33× report_incomplete, 33× noop). This is a compiler/template issue, not 34 independent bugs.
Syft SBOM Inventory
| Image | Packages |
|---|---|
ghcr.io/oraios/serena:1.7.0 |
1,678 |
ghcr.io/github/gh-aw-firewall/cli-proxy:0.28.62 |
346 |
ghcr.io/github/gh-aw-mcpg:v0.4.35 |
289 |
ghcr.io/github/gh-aw-firewall/agent:0.28.62 |
587 |
ghcr.io/github/gh-aw-firewall/api-proxy:0.28.62 |
192 |
ghcr.io/github/gh-aw-node |
177 |
grafana/mcp-grafana:1.1.0-alpine |
178 |
ghcr.io/xberg-io/xberg:1.3.6 |
169 |
node:lts-alpine |
165 |
ghcr.io/github/gh-aw-firewall/squid:0.28.62 |
63 |
ghcr.io/github/gh-aw-firewall/router:0.28.62 |
59 |
ghcr.io/github/github-mcp-server:v2.0.2 |
41 |
Total: 3,944 packages across 12 images — byte-identical to 2026-10-18 (no digest changes).
Runner-Guard Taint Analysis Findings
Runner-Guard Score: not reported in this run's output.
| Rule ID | Name | Severity | Affected Workflows |
|---|---|---|---|
| RGS-018 | Suspicious Payload Execution Pattern | High | daily-workflow-security-model.lock.yml, daily-work-queue-formal-verification.lock.yml, credentials-check.yml |
| RGS-012 | Secret Exfiltration via Outbound HTTP Request | High | github-remote-mcp-auth-test.lock.yml |
| RGS-005 | Excessive Permissions on Untrusted Trigger | Medium | agentic-workqueue.yml, agentic_commands.yml, ai-moderator.lock.yml, q.lock.yml, squad.lock.yml |
Issues created: none (all 4 Critical/High findings are duplicates of previously-filed, already-closed issues — see Runner-Guard Analysis below).
Grype Container Vulnerability Findings
| Image | Critical | High | Medium | Low | Negligible |
|---|---|---|---|---|---|
ghcr.io/oraios/serena:1.7.0 |
15 | 355 | 255 | 65 | 734 |
ghcr.io/xberg-io/xberg:1.3.6 |
18 | 113 | 82 | 17 | 122 |
ghcr.io/github/gh-aw-mcpg:v0.4.35 |
9 | 65 | 30 | 14 | 0 |
grafana/mcp-grafana:1.1.0-alpine |
6 | 36 | 16 | 11 | 0 |
ghcr.io/github/github-mcp-server:v2.0.2 |
2 | 13 | 16 | 5 | 8 |
ghcr.io/github/gh-aw-firewall/agent:0.28.62 |
0 | 2 | 337 | 21 | 1 |
node:lts-alpine |
0 | 17 | 25 | 9 | 0 |
ghcr.io/github/gh-aw-node |
0 | 13 | 16 | 8 | 0 |
ghcr.io/github/gh-aw-firewall/router:0.28.62 |
0 | 0 | 14 | 1 | 1 |
ghcr.io/github/gh-aw-firewall/api-proxy:0.28.62 |
0 | 2 | 4 | 0 | 0 |
ghcr.io/github/gh-aw-firewall/cli-proxy:0.28.62 |
0 | 2 | 4 | 0 | 0 |
ghcr.io/github/gh-aw-firewall/squid:0.28.62 |
0 | 1 | 3 | 0 | 0 |
The ghcr.io/oraios/serena and ghcr.io/xberg-io/xberg images (third-party MCP server images) account for 33 of the 50 Critical findings — mostly curl/libcurl, libxml2, libtiff6, and openssl/libssl CVEs with fixed versions already published upstream.
Yamllint YAML Linting Findings
Clean — 0 findings across all 345 files.
Shellcheck Shell Linting Findings
| Code | Count | Affected Workflows |
|---|---|---|
| SC1003 | 2 | sergo.lock.yml (also flagged by actionlint's embedded shellcheck pass — same underlying finding, not double-counted as a distinct issue) |
| SC2086 | 1 | daily-hippo-learn |
| SC2086 | 1 | hippo-embed |
Top Priority Issues
1. zizmor secrets-outside-env (Medium, 340/345 workflows, 12,573 occurrences)
- Tool: zizmor
- Severity: Medium
- Impact: Jobs reference
secrets.*without a dedicated GitHubenvironment:, so any code running in that job (including anything reachable via prompt injection into an agentic step) has ambient access to every secret visible to the job, with no approval gate or scoping. - Reference: (docs.zizmor.sh/redacted)
- By far the largest cluster in the repo and growing roughly proportionally with workflow count; see Fix Suggestion below.
2. zizmor High: unpinned-images + bot-conditions — 17+ consecutive days with no fix issue filed
- Tool: zizmor
- Count: 2 (1 each)
- Severity: High
- Affected:
smoke-service-ports.lock.yml(unpinned-images),squad.lock.yml(bot-conditions) - Description:
unpinned-images— a container image reference uses a floating tag instead of a digest.bot-conditions— a workflow condition checksgithub.actor(or similar) against a bot identity, which is spoofable by any user who can control that field. - Impact: Unlike the runner-guard Critical/High findings, no dedicated tracking issue currently exists for either of these (they are not in the runner-guard auto-issue-creation scope). This repo's own process has a gap here — recommend filing issues manually.
- Reference: (docs.zizmor.sh/redacted), (docs.zizmor.sh/redacted)
3. grype Critical CVEs in third-party MCP images (50 findings)
- Tool: grype
- Count: 50 Critical (18
xberg, 15serena, 9gh-aw-mcpg, 6mcp-grafana, 2github-mcp-server) - Severity: Critical
- Impact: Base-image CVEs in curl/libxml2/libtiff/openssl with fixed versions already available upstream; these are third-party images gh-aw depends on, not code in this repo.
4. runner-guard RGS-018 / RGS-012 (High, 4 findings) — already triaged, false positives / accepted
- Tool: runner-guard
- Count: 4
- Severity: High
- Affected:
daily-workflow-security-model.lock.yml,daily-work-queue-formal-verification.lock.yml,credentials-check.yml(RGS-018);github-remote-mcp-auth-test.lock.yml(RGS-012) - Description: RGS-018 ("Suspicious Payload Execution Pattern") flags checksum-verified, pinned
curl+sha256sum --check --strict+ extract tool installs (JRE/TLA+/TLC/Agy CLI) — no actual eval/decode/C2 pattern present. RGS-012 flags a pinned, reviewed handshake call toapi.githubcopilot.comthat already carries an inline# runner-guard:ignore RGS-012suppression comment the scanner doesn't appear to honor. - See Runner-Guard Analysis section for full dedup detail.
Fix Suggestion for secrets-outside-env (zizmor)
Issue: Secrets referenced in a job that has no dedicated environment: protection
Severity: Medium
Affected Workflows: 340 of 345 (12,573 occurrences) — by far the largest zizmor cluster, growing roughly proportionally with workflow count
Prompt to Copilot Agent:
You are fixing a security vulnerability identified by zizmor.
Vulnerability: secrets-outside-env - secrets referenced without a dedicated environment
Rule: secrets-outside-env - (docs.zizmor.sh/redacted)
Current Issue:
A job references one or more `secrets.*` values (directly, or indirectly via
steps that consume org/repo secrets) but the job has no `environment:` key.
GitHub Environments let you attach protection rules (required reviewers,
wait timers, deployment branch restrictions) and scope which secrets are
even visible to a job. Without a declared environment, any code that runs
in that job -- including anything reachable via prompt injection into an
agentic step -- has ambient access to every secret available to the
job/repo, with no additional approval gate and no scoping.
Note: gh-aw generates these `.lock.yml` files from `.md` workflow sources
via a shared Go compiler template (not hand-written per workflow), and the
finding appears in nearly all 340 workflows on the same job (typically
`activation` or similar). This is a compiler/template-level issue, not a
per-workflow one -- fixing the shared job template that emits secrets
usage is far more effective than editing hundreds of generated lock files
by hand.
Required Fix:
1. Identify the shared Go template/source that emits the job flagged by
zizmor (check pkg/workflow/*.go or the .md frontmatter compiler for the
job name shown in the finding, e.g. `activation`).
2. Determine which secrets that job actually needs (e.g. `secrets.GITHUB_TOKEN`,
an LLM provider API key, a GH App private key).
3. Add an `environment:` key to that job specifying a named GitHub
Environment (e.g. `environment: agent-runtime`), OR, if per-workflow
environments aren't desired, document why the risk is accepted and add
a `# zizmor: ignore[secrets-outside-env]` suppression with a one-line
justification comment -- only if a security reviewer has confirmed the
job's blast radius is already minimal (e.g. read-only permissions).
4. If introducing a real environment: create/configure the environment in
repo settings (required reviewers / branch restrictions as appropriate),
and confirm the job's secrets access still works in CI.
5. Recompile all workflows (`gh aw compile` or equivalent, per this repo's
`make recompile` target) and re-run zizmor to confirm the finding count
drops for every regenerated workflow, not just one.
Example:
Before:
```yaml
jobs:
activation:
needs: pre_activation
if: needs.pre_activation.outputs.activated == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@...
with:
token: ${{ secrets.GITHUB_TOKEN }}
After:
jobs:
activation:
needs: pre_activation
if: needs.pre_activation.outputs.activated == 'true'
environment: agent-runtime
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@...
with:
token: ${{ secrets.GITHUB_TOKEN }}Please apply this fix at the shared compiler-template level (not to
individual .lock.yml files) so it takes effect across all 340 affected
workflows on the next compile. Validate against a sample of affected
workflows, and re-run the static-analysis scan to confirm the count drops
from 12,573 toward 0 (or to a documented, justified residual with ignore
annotations).
### Runner-Guard Analysis
Dedup logic was applied to all 4 Critical/High runner-guard findings before considering new issues:
| Finding | File | Search result | Action |
|---------|------|----------------|--------|
| RGS-018 | `daily-workflow-security-model.lock.yml` | **Closed** issue #68606 found | Skip (already reviewed/closed) |
| RGS-018 | `daily-work-queue-formal-verification.lock.yml` | **Closed** issue #68607 found | Skip (already reviewed/closed) |
| RGS-018 | `credentials-check.yml` | **Closed** issue #68608 found | Skip (already reviewed/closed) |
| RGS-012 | `github-remote-mcp-auth-test.lock.yml` | `search_issues` calls for this file name were blocked by the repo's content-integrity filter (empty result + "30 item(s) removed by integrity policy", for 4 different query phrasings) | Resolved via cache-memory history instead: this finding has recurred unchanged since 2026-08-25 and is covered by **closed** issue #55652 (reviewed/accepted — pinned, non-attacker-controlled `api.githubcopilot.com` MCP handshake). Not re-filed. |
**Result: 0 new issues created this run.**
Notable: the issue numbers for the three 2026-10-14 RGS-018 filings had gone unrecorded in this scan's persistent memory for 5 consecutive days (2026-10-15 through 2026-10-18), each of those runs noting "tracking gap, numbers not recorded" because `search_issues`/`list_issues` were blocked by the same content-integrity filter on every attempt. This run's search succeeded for the RGS-018 + filename query shape (even though the RGS-012 + `github-remote-mcp-auth-test` shape was still filtered), which resolved the gap — #68606/#68607/#68608 are now recorded in cache memory (`fix-templates/runner-guard-RGS-018.md`) for future runs.
RGS-012's source file already contains an inline `# runner-guard:ignore RGS-012 -- pinned request to the official GitHub remote MCP endpoint...` suppression comment, but the scanner still reports the finding — worth investigating whether this runner-guard version/invocation honors that annotation syntax at all.
### Historical Trends
- **Previous Scan**: 2026-10-18 ([issue #69850](https://github.com/github/gh-aw/issues/69850))
- **Total Findings Then**: 20,477
- **Total Findings Now**: 20,528
- **Change**: +51 (+0.25%)
Movers: zizmor +48 (secrets-outside-env +30, self-repository +7, undocumented-permissions +7, adhoc-packages +3, artipacked +1); grype +3 (high/medium/low +1 each, critical flat at 50 — vuln-DB rescoring noise, no image digest changes). poutine, actionlint, runner-guard, yamllint, shellcheck, and syft are all byte-identical to 2026-10-18.
#### New Issues
None — no new rule types appeared this run.
#### Resolved Issues
None this run. For context: the zizmor `github-app` High finding (unscoped GitHub App token in `squad-*.lock.yml`, open ~2026-09-04 through 2026-10-03) was resolved on 2026-10-03 and remains resolved. The actionlint/shellcheck SC1003 regression affecting 33 workflows (introduced 2026-09-12) was resolved by 2026-10-14 — only `sergo.lock.yml` remains.
#### Still-open, long-unaddressed findings (worth escalating)
- zizmor High `unpinned-images` (`smoke-service-ports.lock.yml`) and `bot-conditions` (`squad.lock.yml`) — **17+ consecutive scan days open, no fix issue ever filed** (first seen ~2026-10-02/03 after `github-app` was resolved; the underlying scan history goes back further for the rule set as a whole).
- runner-guard RGS-018 (3 workflows) — recurs daily even though already triaged and closed as false positives on 2026-10-14; will keep recurring until suppression comments are added to the source (see Fix Suggestion pattern in `fix-templates/runner-guard-RGS-018.md`).
### Recommendations
1. **Immediate**: File a dedicated issue for the two long-standing zizmor High findings (`unpinned-images`, `bot-conditions`) — they are the only Critical/High findings in this report with no tracking issue at all.
2. **Immediate**: Fix or formally accept-and-suppress the RGS-018 false-positive cluster (3 workflows) so it stops resurfacing on every scan.
3. **Short-term**: Apply the `secrets-outside-env` fix at the compiler-template level (see Fix Suggestion) — this single change would eliminate ~61% of all findings in this report.
4. **Short-term**: Fix the 132 actionlint `expression` errors (single root cause: safe-outputs conclusion job references nonexistent `needs.*.outputs` properties) and the remaining `sergo.lock.yml` SC1003 shellcheck finding.
5. **Long-term**: Track whether `runner-guard:ignore` inline suppression comments are actually honored by the scanner invocation used in this pipeline — RGS-012's suppression comment appears to be ignored.
6. **Long-term**: Consider pinning/upgrading the `ghcr.io/oraios/serena` and `ghcr.io/xberg-io/xberg` third-party images, which together account for 66% of all grype Critical findings.
### Next Steps
- [ ] File issues for zizmor High `unpinned-images` and `bot-conditions` (currently untracked)
- [ ] Apply the `secrets-outside-env` fix at the shared compiler-template level
- [ ] Add suppression comments (or genuine fixes) for the RGS-018 false-positive cluster
- [ ] Fix the 132 actionlint `expression` errors (single compiler-template root cause)
- [ ] Investigate why the RGS-012 inline suppression comment isn't honored
- [ ] Review grype Critical findings in `serena`/`xberg` third-party images for available upstream fixes
**References:**
- Workflow run: [§39201468383](https://github.com/github/gh-aw/actions/runs/39201468383)
Generated by 📊 Static Analysis Report · claude · agent · 288.9 AIC · ⌖ 0.996 AIC · ⊞ 7.1K · ◷
- expires on Oct 25, 2026, 9:32 PM UTC-08:00
Activity
github-actions commentedon Oct 20, 2026
This issue is being closed as outdated. A newer issue has been created: #70437
View newer issue
This action was performed automatically by the
Static Analysis Reportworkflow.