Skip to content

[static-analysis] Report - 2026-08-07 #51005

Description

@github-actions

Analysis Summary

  • Tools Used: zizmor, poutine, actionlint, runner-guard, syft, grype, yamllint, shellcheck
  • Total Findings: 2,755 (excluding SBOM package inventory) — up from 2,682 on 2026-08-06 (+73, +2.7%)
  • Workflows Scanned: 276 (up from 275 — one new workflow, daily-vulnhunter-scan.md)
  • Workflows Affected: ~19 workflows carry at least one finding from a security/lint tool (excludes container CVEs, which affect 16 images used across many workflows)
  • Compile Result: 276 succeeded, 174 compiler warnings, 0 failures

Findings by Tool

Tool Total Critical High Medium Low
zizmor (security) 9 0 0 0 0 (info)
poutine (supply chain) 11 0 10 (error) 0 1 (warning)
actionlint (linting) 6 - - - -
runner-guard (taint analysis) 121 0 110 11 0
syft (SBOM inventory) 16 images / 5,354 packages - - - -
grype (container CVEs) 2,607 114 743 1,129 257 (+294 negligible, +70 unknown)
yamllint (yaml linting) 0 - - - -
shellcheck (shell linting, standalone) 1 - - - 1 (note)

Clustered Findings by Tool and Type

Zizmor Security Findings

Issue Type Severity Count Affected Workflows
github_action_from_unverified_creator_used Info 9 copilot-setup-steps.yml, daily-elixir-credo-snippet-audit, dataflow-pr-discussion-dataset, hippo-embed, link-check.yml (x2), mcp-inspector, smoke-codex, super-linter

All 9 already carry # zizmor: ignore[...] annotations — informational only, no action needed. Unchanged from 2026-08-06.

Poutine Supply Chain Findings

Issue Type Severity Count Affected Workflows
untrusted_checkout_exec Error 10 smoke-workflow-call.lock.yml (5), smoke-workflow-call-with-inputs.lock.yml (5)
pr_runs_on_self_hosted Warning 1 smoke-copilot-arm.lock.yml

Unchanged from 2026-08-06. The # poutine:ignore untrusted_checkout_exec comment is present in these generated .lock.yml files but lands one line above the flagged run: step (an off-by-one in source-map generation), so poutine still reports it — see the standing fix suggestion in the "Runner-Guard" recommendations below and prior reports (e.g. #50789).

Actionlint Linting Issues

Issue Type Count Affected Workflows
shellcheck: SC2016 (Expressions don't expand in single quotes) 6 daily-arxiv-researcher.lock.yml (2), daily-code-metrics.lock.yml (2), smoke-crush.lock.yml (2)

Unchanged from 2026-08-06.

Syft SBOM Inventory

16 images, 5,354 total packages
Image Packages
ghcr.io/github/serena-mcp-server:sha-891c160 2,314
ghcr.io/github/gh-aw-firewall/agent:0.27.44 532
ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.44 348
mcp/context7 329
ghcr.io/github/gh-aw-mcpg:v0.4.8 286
mcp/memory 253
grafana/mcp-grafana 252
ghcr.io/github/gh-aw-firewall/api-proxy:0.27.44 193
mcp/ast-grep:latest 186
ghcr.io/github/gh-aw-node 177
mcp/arxiv-mcp-server 168
node:lts-alpine 165
ghcr.io/github/gh-aw-firewall/squid:0.27.44 63
ghcr.io/github/github-mcp-server:v1.8.0 40
python:alpine 38
ghcr.io/fabio-rovai/open-ontologies:latest 10

All image versions are unchanged from 2026-08-06 (no base-image bumps detected this scan).

Runner-Guard Taint Analysis Findings

Rule ID Name Severity Count Affected Workflows
RGS-004 Comment-Triggered Workflow Without Author Authorization Check High 96 dev-hawk.lock.yml
RGS-012 Secret Exfiltration via Outbound HTTP Request High 10 daily-byok-ollama-test.lock.yml, daily-model-inventory.lock.yml, docs-noob-tester.lock.yml, visual-regression-checker.lock.yml
RGS-018 Suspicious Payload Execution Pattern High 4 daily-byok-ollama-test.lock.yml, daily-cli-performance.lock.yml, daily-sentrux-report.lock.yml, smoke-claude.lock.yml
RGS-005 Excessive Permissions on Untrusted Trigger Medium 9 agentic_commands.yml, ai-moderator.lock.yml, q.lock.yml
RGS-019 Step Output Interpolated in run Block Medium 2 error-message-lint.yml, windows-cli-integration.yml

All counts are unchanged from the 2026-08-06 scan (3rd consecutive day with identical runner-guard output).

Issues created: none. All 9 High-severity (rule, file) combinations map to previously-created issues that are already closed; per dedup policy, closed matches are skipped rather than recreated. Medium-severity findings (RGS-005, RGS-019) are not eligible for new-issue creation per policy.

Runner-Guard issue dedup detail
Finding Status Action
RGS-004 in dev-hawk.lock.yml Closed (#50189) Skipped — reviewed and closed
RGS-012 in daily-model-inventory.lock.yml Closed (#30776) Skipped — reviewed and closed
RGS-012 in daily-byok-ollama-test.lock.yml Closed (#35652) Skipped — reviewed and closed
RGS-012 in visual-regression-checker.lock.yml Closed (#30947) Skipped — reviewed and closed
RGS-012 in docs-noob-tester.lock.yml Closed (#50190) Skipped — reviewed and closed
RGS-018 in smoke-claude.lock.yml Closed (#47477) Skipped — reviewed and closed
RGS-018 in daily-cli-performance.lock.yml Closed (#47478) Skipped — reviewed and closed
RGS-018 in daily-sentrux-report.lock.yml Closed (#46532) Skipped — reviewed and closed
RGS-018 in daily-byok-ollama-test.lock.yml Closed (#35653) Skipped — reviewed and closed

Grype Container Vulnerability Findings

Image Critical High Total
ghcr.io/github/serena-mcp-server:sha-891c160 64 389 1,113
mcp/arxiv-mcp-server 16 115 410
ghcr.io/github/gh-aw-firewall/agent:0.27.44 0 4 372
mcp/context7 10 76 171
grafana/mcp-grafana 7 19 162
mcp/memory 8 58 125
mcp/ast-grep:latest 6 38 95
ghcr.io/github/gh-aw-firewall/squid:0.27.44 0 14 22
node:lts-alpine 1 6 22
ghcr.io/github/gh-aw-mcpg:v0.4.8 0 6 21
ghcr.io/github/gh-aw-firewall/api-proxy:0.27.44 0 4 19
ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.44 0 4 18
ghcr.io/fabio-rovai/open-ontologies:latest 1 2 17
ghcr.io/github/github-mcp-server:v1.8.0 1 3 14
ghcr.io/github/gh-aw-node 0 2 14
python:alpine 0 3 12

serena-mcp-server and mcp/arxiv-mcp-server remain the two heaviest images (1,113 and 410 findings, ~58% of all container CVE findings combined). Only ghcr.io/github/gh-aw-firewall/agent:0.27.44 moved this scan (370 → 372, +2 Medium-severity findings, same image tag — likely upstream advisory metadata update rather than an image rebuild). All other images are byte-for-byte unchanged from 2026-08-06 (same digests). The +72 grype delta vs. yesterday is mostly a reclassification: 70 findings that previously fell inside another severity bucket are now reported as a distinct [Unknown] severity across serena-mcp-server, mcp/arxiv-mcp-server, grafana/mcp-grafana, and gh-aw-mcpg — worth a spot check that this isn't masking newly-unrated CVEs.

Yamllint YAML Linting Findings

No issues — 0 findings across 276 files.

Shellcheck Shell Linting Findings

One new finding from the standalone shellcheck pass:

Code Count Affected Workflows
SC2015 1 daily-vulnhunter-scan.lock.yml

script:29:20: note: Note that A && B || C is not if-then-else. C may run when A is true. in the "Prepare VulnHunter bundle" step. This is a newly-added workflow this scan (workflow count rose 275 → 276) — no prior open/closed issue exists for this finding. Severity is note (informational); not eligible for automatic issue creation under the runner-guard-only policy, but flagged here for awareness.

Top Priority Issues

1. Runner-Guard RGS-004 — dev-hawk.lock.yml (96 occurrences, single workflow, false-positive-at-scale)

  • Tool: runner-guard
  • Count: 96
  • Severity: High
  • Affected: dev-hawk.lock.yml
  • Description: dev-hawk.md is triggered by workflow_run and gates its job with contains(fromJSON('["pelikhan", ...]'), github.event.workflow_run.actor.login) — a hardcoded actor allowlist. runner-guard's RGS-004 rule only recognizes author_association checks as valid authorization gates, so it flags every one of the ~96 generated steps in the compiled lock file individually.
  • Impact: Verified via source inspection (.github/workflows/dev-hawk.md lines 8-17): the job-level if: restricts execution to 9 named trusted logins, and granted permissions are read-only (contents: read, actions: read, pull-requests: read). This is very likely a false positive — the workflow already has an equivalent (arguably stronger, since it's a fixed allowlist rather than a dynamic role check) authorization gate. The 96x repetition per scan is pure noise. Previously tracked and closed in [static-analysis] RGS-004: Comment-Triggered Workflow Without Author Authorization Check in dev-hawk.lock.yml #50189.
  • Reference: n/a (in-repo runner-guard rule) — see Fix Suggestion below for a detailed triage/remediation prompt.

2. Poutine untrusted_checkout_exec — ignore-comment off-by-one (recurring, unresolved)

  • Tool: poutine
  • Count: 10
  • Severity: Error (High)
  • Affected: smoke-workflow-call.lock.yml, smoke-workflow-call-with-inputs.lock.yml
  • Description: Steps running bash "${RUNNER_TEMP}/gh-aw/actions/*.sh" are flagged as "Arbitrary Code Execution from Untrusted Code Changes" even though a # poutine:ignore untrusted_checkout_exec comment exists in the source, because the compiler emits the comment above env: rather than immediately above run:.
  • Impact: Permanent unactionable noise in every scan (10 findings/day, unchanged for 3+ days). Root-caused and a fix prompt provided in [static-analysis] Report - 2026-08-06 #50789 (2026-08-06 report) — still not applied as of this scan.
  • Reference: https://github.com/boostsecurityio/poutine/blob/main/docs/rules/untrusted_checkout_exec.md

Fix Suggestion for Runner-Guard RGS-004

Issue: RGS-004 doesn't recognize actor-allowlist if: gates (contains(fromJSON(...), <event>.actor.login)) as equivalent to an author_association check, causing 96 redundant high-severity findings per scan on a single already-reviewed workflow.
Severity: High
Affected Workflows: 1 workflow (96 findings)

Prompt to Copilot Agent:

You are triaging a security finding from runner-guard, a CI/CD taint-analysis scanner.

**Vulnerability**: RGS-004 - Comment-Triggered Workflow Without Author Authorization Check

**Rule rationale**: workflows triggered by `issue_comment`, `pull_request_review_comment`, or
`workflow_run` can be invoked by ANY GitHub user (including non-collaborators). If such a workflow
has secrets access or write permissions and does not check the triggering actor's authorization
level, any external user can invoke privileged operations.

**Current situation**:
`.github/workflows/dev-hawk.md` (compiled to dev-hawk.lock.yml) is triggered by `workflow_run` and
gates the entire job with:

    if: |
      ${{ github.event.workflow_run.event == 'workflow_dispatch' &&
      contains(fromJSON('["pelikhan","cmuto09","dsyme","mnkiefer","davidslater","zarenner","lpcox","salmanmkc","gh-aw-bot"]'), github.event.workflow_run.actor.login) }}

This IS an authorization check — it restricts execution to a fixed allowlist of trusted GitHub
logins — but it is not the `author_association` pattern RGS-004 looks for, so the rule fires on
every generated step (96 times in this workflow alone).

**Required investigation** (do this before changing anything):
1. Confirm the `if:` condition is present at the job level in the compiled `dev-hawk.lock.yml`.
2. Confirm granted `permissions:` are minimal (read-only) — no write scopes.
3. Confirm the actor allowlist only contains real trusted maintainers/bots.

**Fix options**:

Option A (preferred) — the allowlist gate is sufficient; this is a false positive:
  - Do not weaken the workflow. Instead, either (a) check whether runner-guard supports an inline
    per-job suppression comment and add ONE suppression at the job level instead of accepting 96
    redundant findings, or (b) file an upstream feature request against runner-guard asking it to
    recognize `contains(fromJSON(...), <actor path>.login)` job-level `if:` gates as satisfying
    RGS-004, so this stops recurring on every scan without manual suppression.

Option B — defense-in-depth (optional, not required to close the finding):
  - Additionally verify `github.event.workflow_run.actor.login`'s org/repo role via the GitHub API
    as a second gate, in case the hardcoded login list goes stale.

**Example** (once runner-guard supports job-level suppression):
Before:
```yaml
jobs:
  dev_hawk:
    if: |
      ${{ github.event.workflow_run.event == 'workflow_dispatch' &&
      contains(fromJSON('["pelikhan", ...]'), github.event.workflow_run.actor.login) }}
    permissions:
      contents: read
      actions: read

After:

jobs:
  dev_hawk:
    # runner-guard: ignore[RGS-004] -- gated by actor allowlist above, not author_association
    if: |
      ${{ github.event.workflow_run.event == 'workflow_dispatch' &&
      contains(fromJSON('["pelikhan", ...]'), github.event.workflow_run.actor.login) }}
    permissions:
      contents: read
      actions: read

Do not remove or weaken the existing actor-allowlist gate while investigating this finding.


### All Findings Details

<details>
<summary><b>Detailed Findings by Workflow</b></summary>

#### dev-hawk.lock.yml
- **RGS-004** (High) × 96 — every generated step flagged; see Top Priority Issue #1 above for root cause and fix.

#### daily-model-inventory.lock.yml
- **RGS-012** (High) × 4 — outbound HTTP requests to model-provider API endpoints (Anthropic, Gemini, OpenAI, models.dev) in a job with secrets access. Reviewed and closed previously (#30776) as expected behavior for a model-inventory workflow.

#### daily-byok-ollama-test.lock.yml
- **RGS-012** (High) × 3, **RGS-018** (High) × 1 — outbound requests to a self-hosted Ollama endpoint plus an install-script pattern matching a payload-execution signature. Both previously reviewed and closed (#35652, #35653).

#### docs-noob-tester.lock.yml
- **RGS-012** (High) × 1 — closed previously (#50190).

#### visual-regression-checker.lock.yml
- **RGS-012** (High) × 2 — closed previously (#30947).

#### daily-cli-performance.lock.yml / daily-sentrux-report.lock.yml / smoke-claude.lock.yml
- **RGS-018** (High) × 1 each — tool-install scripts (sentrux, MCP scripts config, CLI perf harness) matching Runner Guard's payload-execution signature heuristics. All previously reviewed and closed (#47478, #46532, #47477).

#### agentic_commands.yml / ai-moderator.lock.yml / q.lock.yml
- **RGS-005** (Medium) × 1 / 5 / 3 — write-level permissions combined with an untrusted trigger event. Not eligible for auto-issue creation (medium severity).

#### error-message-lint.yml / windows-cli-integration.yml
- **RGS-019** (Medium) × 1 each — step outputs interpolated directly into `run:` blocks. Not eligible for auto-issue creation (medium severity).

#### smoke-workflow-call.lock.yml / smoke-workflow-call-with-inputs.lock.yml
- **poutine untrusted_checkout_exec** (Error) × 5 each — see Top Priority Issue #2.

#### smoke-copilot-arm.lock.yml
- **poutine pr_runs_on_self_hosted** (Warning) × 1 — runs on `ubuntu-24.04-arm`, flagged as a self-hosted-style runner label; low risk, informational.

#### daily-arxiv-researcher.lock.yml / daily-code-metrics.lock.yml / smoke-crush.lock.yml
- **actionlint shellcheck SC2016** × 2 each — single-quoted strings containing `${{ }}`-style placeholders that look like shell expansions but don't expand; cosmetic, no functional impact.

#### daily-vulnhunter-scan.lock.yml
- **shellcheck SC2015** (note) × 1 — new this scan; `A && B || C` short-circuit pattern in "Prepare VulnHunter bundle" step (line 29) doesn't behave like if/then/else if `B` can fail. Low-risk stylistic note.

</details>

### Historical Trends

- **Previous Scan**: 2026-08-06 (issue #50789)
- **Total Findings Then**: 2,682
- **Total Findings Now**: 2,755
- **Change**: +73 (+2.7%)

#### New Issues
- One new workflow (`daily-vulnhunter-scan.md`) entered the fleet this scan, bringing a new standalone-shellcheck SC2015 finding (informational).
- Grype gained a new **[Unknown]**-severity bucket (70 findings) spread across serena-mcp-server, mcp/arxiv-mcp-server, grafana/mcp-grafana, and gh-aw-mcpg — these appear to be CVEs without a settled severity rating rather than newly introduced vulnerabilities, but worth spot-checking.
- `ghcr.io/github/gh-aw-firewall/agent:0.27.44` gained +2 Medium findings at the same image tag/digest family as before.

#### Resolved Issues
- None — no finding categories dropped out this scan. zizmor, poutine, actionlint, and runner-guard counts are all identical to 2026-08-06 (3rd consecutive day unchanged for those four tools).

### Recommendations

1. **Immediate**: None of today's High/Critical findings are new — all runner-guard High findings map to previously-closed issues (false positives / accepted risk). No urgent action required this cycle.
2. **Short-term**: Apply the standing poutine `untrusted_checkout_exec` comment-placement fix (root-caused in #50789, still outstanding) to permanently clear 10 recurring findings. Spot-check the new grype `[Unknown]`-severity CVEs to confirm they aren't masking a real new vulnerability.
3. **Long-term**: Teach runner-guard's RGS-004 rule to recognize actor-allowlist `if:` patterns as an equivalent gate to `author_association` checks (see Fix Suggestion above) — this would eliminate 96 redundant findings per scan going forward without manual per-workflow suppression.
4. **Prevention**: `serena-mcp-server` and `mcp/arxiv-mcp-server` together account for ~58% of all grype findings (1,523 of 2,607) — still the top candidates for a base-image refresh or slimmer replacement image.

### Next Steps

- [ ] Apply the poutine ignore-comment placement fix in the compiler (smoke-workflow-call*.lock.yml templates) — carried over from #50789
- [ ] Spot-check the 70 new grype `[Unknown]`-severity findings for genuinely new/unrated CVEs
- [ ] Evaluate teaching RGS-004 to recognize actor-allowlist authorization patterns (fix prompt above)
- [ ] Consider a base-image refresh pass for serena-mcp-server and mcp/arxiv-mcp-server (highest CVE fan-out)
- [ ] No new GitHub issues required this cycle — all High/Critical runner-guard findings map to already-closed prior issues

> Generated by [📊 Static Analysis Report](https://github.com/github/gh-aw/actions/runs/31149816433) · agent · 139.6 AIC · ⌖ 43.4 AIC · ⊞ 11.1K · [◷](https://github.com/search?q=repo%3Agithub%2Fgh-aw+is%3Aissue+%22gh-aw-workflow-call-id%3A+github%2Fgh-aw%2Fstatic-analysis-report%22&type=issues)
> - [x] expires <!-- gh-aw-expires: 2026-08-14T05:40:51.217Z --> on Aug 13, 2026, 9:40 PM UTC-08:00

<!-- gh-aw-agentic-workflow: Static Analysis Report, engine: claude, model: agent, id: 31149816433, workflow_id: static-analysis-report, run: https://github.com/github/gh-aw/actions/runs/31149816433 -->

<!-- gh-aw-workflow-id: static-analysis-report -->
<!-- gh-aw-workflow-call-id: github/gh-aw/static-analysis-report -->

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions