Upgrade deps + add govulncheck - #539
Merged
Merged
Conversation
Clears 7 Critical advisories that started failing .github/workflows/scan.yml once the grype vulnerability DB picked them up (v6.1.9, built 2026-08-14). Identifiers cross-checked against OSV: CVE-2026-46595 GO-2026-5023 (10.0) VerifiedPublicKeyCallback permissions skip enforcement CVE-2026-42508 GO-2026-5021 (9.1) auth bypass via unenforced @Revoked status CVE-2026-39830 GO-2026-5017 (9.1) client can cause server deadlock on unexpected responses CVE-2026-39831 GO-2026-5019 (9.1) FIDO/U2F security key physical presence check bypass CVE-2026-39832 GO-2026-5006 (9.1) agent constraints not dropped when forwarding keys CVE-2026-39833 GO-2026-5005 (9.1) invoking key constraints not enforced CVE-2026-39834 GO-2026-5020 (9.1) infinite loop on large channel writes All of them live in golang.org/x/crypto/ssh, which kool never reaches: x/crypto enters the build as an indirect dependency via services/updater -> go-github-selfupdate -> go-github/v30 -> x/crypto/openpgp. Grype matches Go modules at module granularity from the binary's buildinfo, so it cannot tell that only openpgp is linked; govulncheck, which resolves at package and symbol granularity, does not report any of the seven. Bumping is still cheaper than carrying seven ignore entries. go mod tidy pulls the rest of the x/* set along (net v0.54.0, sys v0.45.0, term v0.43.0, text v0.37.0) and drops the now-redundant explicit x/net requirement -- it still resolves to v0.54.0 through the module graph. Verified by rebuilding the image and rescanning: Criticals 7 -> 0, so the severity-cutoff: critical gate passes. Highs are unchanged at 14, all below the gate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The entry was added as an explicitly temporary unblock after the docker:27-cli -> docker:29-cli base bump, to be removed once upstream rebuilt the image with go1.25.9+. That has happened: scanning docker:29-cli straight from the registry with no config now reports 0 Critical findings, and CVE-2026-27143 no longer appears in a scan of kooldev/kool at all. Keeps .grype.yaml itself with an empty ignore list so the policy it documents survives -- upstream-inherited CVEs may be ignored with a tracker link, our own code and dependencies get fixed. Also drops the now-obsolete go1.25.8/CVE-2026-27143 example from the CI integration docs. The general caveat about inheriting Docker's plugin binaries still holds, so the section stays; only the specific advisory that has since cleared is gone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
anchore/scan-action defaults to output-format: sarif and writes the report to a temp file that is discarded when the job ends. On failure the log contained only: ERROR discovered vulnerabilities at or above the severity threshold Failed minimum severity level. Found vulnerabilities with level 'critical' or higher No CVE, no package, no version. Diagnosing the x/crypto criticals that broke this workflow required rebuilding the image locally and rescanning by hand. Adds a Report findings step that prints a severity histogram plus the findings at or above the cutoff. `if: always()` is load-bearing -- the scan step fails the job, so a step without it is skipped exactly when its output is wanted. Notes on the details: - severity-cutoff moves to a job-level SEVERITY_CUTOFF env so the gate and the report cannot drift apart. The jq ranks severities rather than matching the cutoff exactly, so raising or lowering it keeps reporting the right set. - The filter reads grype's own severity word out of the SARIF message text, not the SARIF `level` field: level collapses high and critical into "error", which would over-report against a critical cutoff. - by-cve: true so findings read as CVE-2026-46595 rather than GHSA-x527-x647-q7gg. Deliberately not uploading the SARIF to code scanning. That would publish every severity as an open alert, including the 14 Highs the critical-only gate does not fail on, and it needs security-events: write while still failing for fork PRs. Printing solves the actual problem without the alert-triage burden. Verified by running the step's script against real grype SARIF output: a scan with criticals renders the histogram and finding list, and a missing report exits 0 with an explanation rather than erroring. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The grype image scan matches Go modules at module granularity from the
binary's buildinfo, so it cannot tell which packages are actually
linked. That is how seven x/crypto/ssh criticals came to fail a build
for a binary that only links x/crypto/openpgp. govulncheck resolves to
called symbols and reports neither -- it does not even list them, since
kool never imports x/crypto/ssh.
The two tools do not overlap much in practice:
grype OS/apk packages, the docker:29-cli compose and buildx
plugin binaries, Go modules at module granularity
CodeQL code-level SAST
govulncheck Go modules and stdlib at symbol granularity, with
reachability
Running it against the current tree already surfaces something the
critical-only grype gate never will: GO-2026-5932, x/crypto/openpgp is
unmaintained and unsafe by design, reachable via
services/updater/updater.go -> selfupdate.init -> openpgp.init, with no
fix available. The real remedy is replacing rhysd/go-github-selfupdate,
which also pins go-github/v30; that would drop x/crypto from the build
entirely.
Report-only for now, deliberately:
- govulncheck has no suppression file the way grype has .grype.yaml, so
a finding cannot be waived declaratively.
- GO-2026-5932 has no fix, so gating would pin the build red until the
self-updater is replaced.
- stdlib findings churn with every Go patch release.
A genuine tool failure still fails the job: exit 3 means
vulnerabilities were found and is reported without failing, anything
else non-zero propagates. govulncheck is installed rather than invoked
through `go run`, which collapses every non-zero exit to 1 and would
erase that distinction.
The job pins go-version 1.25.x to match both test.yml and the golang:1.25
the Dockerfile pulls, so CI and a local `kool run govulncheck` agree on
which stdlib advisories still apply -- a stale local golang image
reports against go1.25.9 while a pulled build produces go1.25.13.
Results also go to $GITHUB_STEP_SUMMARY so a report-only job stays
visible without being buried in the log.
Verified: the step script was run against simulated exits 0, 3 and 2 --
passing, passing with findings, and failing respectively -- and
`kool run govulncheck` reproduces the CI findings locally.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Clears GO-2026-5970, an infinite loop on invalid input, which govulncheck reported against the imported package. v0.37.0 came in with the x/crypto bump; the advisory is fixed in v0.39.0. `kool run test` passes across all 13 packages. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Notes