vulnscan

command
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 26, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Command vulnscan runs govulncheck as a CI security gate that cannot be silenced by an upstream outage and cannot silently pass because of one.

It exists because the obvious invocation —

go run golang.org/x/vuln/cmd/govulncheck@latest ./pkg/...

has three independent defects, and the fix for each is why a wrapper is warranted at all:

  1. It fetches the vulnerability database over the network on EVERY job, one request per advisory. A fleet of self-hosted runners sharing a small block of addresses gets rate-limited into `403 Forbidden`, and the job reports that as a FAILED SECURITY GATE. Fixed by mirroring the database locally (mirror.go): one request per refresh window, zero in steady state.

  2. `@latest` re-resolves the tool on every run, so the gate's verdict can change with no diff in this repository — and the resolution is itself another network dependency that can fail. Fixed by pinning govulncheckVersion below.

  3. Its exit code alone cannot distinguish "found nothing" from "could not look". Pointed at an empty directory, govulncheck exits 0 and emits a well-formed, zero-finding report. Fixed by classifying on the scanner's own machine-readable output (classify.go), which is why this runs with `-format json` rather than parsing prose.

  4. Its coverage of the STANDARD LIBRARY is silently conditional on the toolchain's version string, and a run whose stdlib half never happened is byte-for-byte indistinguishable from a clean one. Measured: under a locally rebuilt `go1.26.5-X:nodwarf5` toolchain the scan reported no called vulnerabilities against the same database on which stock go1.26.5 reports four. Fixed by making a clean verdict require a released toolchain (classify.go), so the gate is only quiet when it actually looked everywhere it claims to.

The two halves are held apart deliberately. A fetch failure is retried and, with a mirror inside the staleness bound, tolerated — that is defect 1. A scan that ran and found a called vulnerability fails the build, and a scan that could not consult a database fails the build with a DIFFERENT message — neither is ever reported as clean. Retries apply only to the fetch, never to a verdict, so no amount of retrying can turn a real finding into a pass.

Fleet-wide serialisation via a workflow `concurrency:` group was considered and rejected: it would queue five runners behind one scan, adding PR latency proportional to fleet size, and it only narrows the window — a single serialised job still issues hundreds of per-advisory requests and can still be refused. The mirror removes the requests instead of spacing them out.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL