Publish release binaries govulncheck can assess - #37
Publish release binaries govulncheck can assess#37ai-collaboration-app[bot] wants to merge 2 commits into
Conversation
GoReleaser built with `-s`, which strips the symbol table, so `govulncheck -mode=binary` on a published asset cannot see which packages are actually linked and falls back to reporting every symbol an advisory names. The v0.8.4 assets therefore report GO-2026-5932 (the unmaintained `x/crypto/openpgp` packages) as affected, while the same check on an unstripped build of the same commit reports 0 affected — `golang.org/x/crypto/sha3`, pulled in by go-playground/validator, is the only x/crypto package in the graph. `-w` still drops DWARF, so the cost is ~16% on the raw binary and ~7% on the archive. In exchange the artifact carries its own reachability evidence, which is what our release-asset scan lane and Rancher's govulncheck-derived VEX automation both read. Co-authored-by: Cve Ticket Reconciler <cve-ticket-reconciler@stackstate.invalid>
The source-mode govulncheck run says nothing about the artifacts we ship: it reads packages, not the linked binary, so it stays green whether or not the build strips its symbol table. Running it in binary mode over each prepared release binary closes that gap — it fails if `-s` returns to the ldflags, and it fails if a vulnerable package ever does become reachable from the shipped binary, including one reached only through the embedded toolchain. Both govulncheck invocations now share one pinned version. Co-authored-by: Cve Ticket Reconciler <cve-ticket-reconciler@stackstate.invalid>
| status=0 | ||
| for binary in "${binaries[@]}"; do | ||
| echo "== ${binary}" | ||
| if ! go run "golang.org/x/vuln/cmd/govulncheck@${govulncheck_version}" -mode=binary "${binary}"; then |
There was a problem hiding this comment.
[P2] Assert that each binary is assessable before trusting govulncheck. govulncheck returning non-zero on a stripped binary is contingent on the current vulnerability database containing an advisory for one of its modules; it is not itself an assessability check. I reproduced the current behavior: the unstripped PR head returns 0, while the same build with -s -w returns 3 only because x/crypto currently has GO-2026-6303 and GO-2026-5932. If a future dependency update drops or fixes those modules, a stripped binary can return 0 and this gate would silently publish an artifact that future advisories cannot assess. Please explicitly fail unless each artifact contains usable Go symbols (for example, verify a known Go symbol with go tool nm, with a test proving an -s -w build is rejected) before invoking govulncheck.
.goreleaser.ymlbuilt with-s, so the published binaries carry no symbol table andgovulncheck -mode=binarycannot tell which packages are linked. It therefore reports GO-2026-5932 (x/crypto/openpgp) as affected against every v0.8.4 asset, verified on the downloaded release archive. Dropping-s(keeping-w) turns that into 0 affected on an otherwise identical build of the same commit; the onlyx/cryptopackage in the graph issha3. Cost is ~7% archive size.The second commit adds the binary-mode run to the
securityjob, so a future-s, or a package that genuinely does become reachable, fails the release instead of shipping an artifact nobody can assess.Tracking: https://github.com/StackVista/cve-reporter/issues/57
Finding revision:
sha256:28c71a3f80d8d62ba642832f0bafa2af1082d2918fdd2b7d8c0c8a5d6cb0dd76Validated locally on
b4c875d+ this branch:go test ./...green, source and binary-mode govulncheck as described, cross-built all five targets, Trivy vulnerability + secret and Grype scans over the packaged rootfs.