Skip to content

Upgrade deps + add govulncheck - #539

Merged
fabriciojs merged 5 commits into
mainfrom
upgrade-deps
Aug 15, 2026
Merged

Upgrade deps + add govulncheck#539
fabriciojs merged 5 commits into
mainfrom
upgrade-deps

Conversation

@fabriciojs

Copy link
Copy Markdown
Member
Issue #
🪲 Bug Fix No/Yes
🧰 Improvement No/Yes
🏆 Feature No/Yes
📝 Refactor No/Yes
❌ Removed No/Yes
📖 Documentation No/Yes
⚠️ Break Change No/Yes

Description


Notes

fabriciojs and others added 5 commits August 14, 2026 22:37
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>
@fabriciojs fabriciojs changed the title Upgrade deps Upgrade deps + add govulncheck Aug 15, 2026
@fabriciojs fabriciojs added the release-drafter:changed Release drafter: Changed label Aug 15, 2026
@fabriciojs
fabriciojs merged commit bb95d1b into main Aug 15, 2026
9 checks passed
@fabriciojs
fabriciojs deleted the upgrade-deps branch August 15, 2026 01:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-drafter:changed Release drafter: Changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant