mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
chore: accept known vulnerabilities with an expiry
The vulnerability scan failed preflight on a containerd advisory that dev already carries and that is deferred to a separate dependency update. The gate now passes only reachable findings listed with an expiry date, fails on any new one or on an expired acceptance, and warns when an acceptance is no longer needed.
This commit is contained in:
@@ -412,7 +412,7 @@ fix:
|
||||
|
||||
govulncheck:
|
||||
@echo "Running govulncheck..."
|
||||
$(_Q)scripts/run-gate.sh govulncheck go tool govulncheck ./...
|
||||
$(_Q)scripts/run-gate.sh govulncheck scripts/govulncheck-gate.sh
|
||||
@echo " govulncheck ok"
|
||||
|
||||
# NilAway — advisory nil-panic analysis. Not in preflight due to false positives
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# Reachable vulnerabilities accepted for a bounded time, read by scripts/govulncheck-gate.sh.
|
||||
# Format: <OSV-ID> <expiry YYYY-MM-DD> <reason>
|
||||
# The gate fails once the expiry passes: fix the dependency or renew deliberately.
|
||||
GO-2026-6597 2026-11-07 containerd v2.4.0 image-pull DoS, fixed in v2.4.1; inherited from dev and deferred to a dependency update outside the package-boundary refactor.
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
# Fails on any reachable vulnerability that is not listed in
|
||||
# govulncheck-accepted.txt, and on any acceptance whose expiry has passed.
|
||||
# Each line is "<OSV-ID> <YYYY-MM-DD expiry> <reason>"; '#' starts a comment.
|
||||
# GOVULNCHECK_JSON substitutes a saved -format json report, for tests.
|
||||
set -euo pipefail
|
||||
|
||||
accepted_file=${GOVULNCHECK_ACCEPTED:-govulncheck-accepted.txt}
|
||||
today=${GOVULNCHECK_TODAY:-$(date -u +%F)}
|
||||
|
||||
if [ -n "${GOVULNCHECK_JSON:-}" ]; then
|
||||
report=$(cat "$GOVULNCHECK_JSON")
|
||||
else
|
||||
report=$(go tool govulncheck -format json ./...)
|
||||
fi
|
||||
|
||||
# A finding whose first trace frame names a function is reachable from our
|
||||
# code; text mode reports only these, so module- and package-level ones pass.
|
||||
mapfile -t called < <(printf '%s\n' "$report" | jq -rs \
|
||||
'[.[] | select(.finding) | .finding | select(.trace[0].function) | .osv] | unique | .[]')
|
||||
|
||||
declare -A expiry reason
|
||||
if [ -f "$accepted_file" ]; then
|
||||
while read -r id until why; do
|
||||
[[ -z "$id" || "$id" == \#* ]] && continue
|
||||
expiry[$id]=$until
|
||||
reason[$id]=$why
|
||||
done <"$accepted_file"
|
||||
fi
|
||||
|
||||
fail=0
|
||||
for id in "${called[@]}"; do
|
||||
if [ -z "${expiry[$id]:-}" ]; then
|
||||
echo " $id is reachable and not accepted; run 'go tool govulncheck ./...' for the trace"
|
||||
fail=1
|
||||
elif [[ "$today" > "${expiry[$id]}" ]]; then
|
||||
echo " $id acceptance expired on ${expiry[$id]}: ${reason[$id]}"
|
||||
fail=1
|
||||
else
|
||||
echo " $id accepted until ${expiry[$id]}: ${reason[$id]}"
|
||||
fi
|
||||
done
|
||||
|
||||
for id in "${!expiry[@]}"; do
|
||||
if ! printf '%s\n' "${called[@]}" | grep -qx "$id"; then
|
||||
echo " $id is accepted but no longer reported; remove it from $accepted_file"
|
||||
fi
|
||||
done
|
||||
|
||||
exit "$fail"
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
#!/bin/sh
|
||||
# Tests the accepted-vulnerability gate against saved reports, so the logic is
|
||||
# checked without running the scanner.
|
||||
set -u
|
||||
|
||||
here=$(cd "$(dirname "$0")" && pwd)
|
||||
gate="$here/govulncheck-gate.sh"
|
||||
tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
|
||||
cat >"$tmp/accepted.txt" <<'EOF'
|
||||
# comment
|
||||
GO-2026-6597 2026-11-07 accepted for the test
|
||||
EOF
|
||||
cat >"$tmp/reachable.json" <<'EOF'
|
||||
{"config":{}}
|
||||
{"finding":{"osv":"GO-2026-6597","trace":[{"module":"m","package":"p","function":"Pull"}]}}
|
||||
{"finding":{"osv":"GO-2026-0001","trace":[{"module":"m"}]}}
|
||||
EOF
|
||||
cat >"$tmp/new.json" <<'EOF'
|
||||
{"finding":{"osv":"GO-2026-6597","trace":[{"module":"m","package":"p","function":"Pull"}]}}
|
||||
{"finding":{"osv":"GO-2026-7777","trace":[{"module":"m","package":"p","function":"F"}]}}
|
||||
EOF
|
||||
echo '{"config":{}}' >"$tmp/clean.json"
|
||||
|
||||
fails=0
|
||||
check() {
|
||||
want=$1 name=$2 report=$3 today=$4 accepted=$5 expect=$6
|
||||
out=$(GOVULNCHECK_JSON="$tmp/$report" GOVULNCHECK_TODAY=$today GOVULNCHECK_ACCEPTED=$accepted bash "$gate" 2>&1)
|
||||
rc=$?
|
||||
if [ "$rc" != "$want" ] || ! printf '%s' "$out" | grep -q "$expect"; then
|
||||
echo "FAIL [$name] rc=$rc want=$want output: $out"
|
||||
fails=$((fails + 1))
|
||||
else
|
||||
echo "ok [$name]"
|
||||
fi
|
||||
}
|
||||
|
||||
check 0 "accepted reachable finding passes" reachable.json 2026-10-07 "$tmp/accepted.txt" "GO-2026-6597 accepted until 2026-11-07"
|
||||
check 0 "expiry day itself still passes" reachable.json 2026-11-07 "$tmp/accepted.txt" "accepted until"
|
||||
check 1 "expired acceptance fails" reachable.json 2026-11-08 "$tmp/accepted.txt" "acceptance expired on 2026-11-07"
|
||||
check 1 "new reachable finding fails" new.json 2026-10-07 "$tmp/accepted.txt" "GO-2026-7777 is reachable and not accepted"
|
||||
out=$(GOVULNCHECK_JSON="$tmp/reachable.json" GOVULNCHECK_TODAY=2026-10-07 GOVULNCHECK_ACCEPTED="$tmp/accepted.txt" bash "$gate" 2>&1)
|
||||
if printf '%s' "$out" | grep -q "GO-2026-0001"; then
|
||||
echo "FAIL [module-level finding is not reachable] output: $out"
|
||||
fails=$((fails + 1))
|
||||
else
|
||||
echo "ok [module-level finding is not reachable]"
|
||||
fi
|
||||
check 0 "fixed finding warns that acceptance is stale" clean.json 2026-10-07 "$tmp/accepted.txt" "no longer reported"
|
||||
check 1 "missing acceptance file fails reachable finding" reachable.json 2026-10-07 "$tmp/none" "not accepted"
|
||||
|
||||
[ "$fails" -eq 0 ] || exit 1
|
||||
Reference in New Issue
Block a user