Repository navigation
Conversation
The gosec version was hard-coded in ci.yml, pre-commit.yml, the Makefile and scripts/gosec-hook.sh, plus comments that restated it. A bump that missed one site would leave local scans and CI's SARIF upload on different gosec rule sets. - Add .gosec-version (v2.28.0, unchanged) as the only place the version is written. ci.yml's Security Scanning job, the Makefile and the pre-commit hook read it; the hook validates it and stops with exit 2 on a missing or malformed file. - Delete pre-commit.yml's gosec install step and drop gosec from its tool-cache key. The gosec hook is SKIPped in that job and installs its own copy under ~/.cache anyway, so ~/go/bin/gosec was never run. - Fix the stale comments: pre-commit.yml no longer claims to track a securego/gosec Action, and the Makefile no longer claims sync with database-migration.yml, which pins none of these tools. - security-scan.sh no longer suggests installing gosec@latest. - Add scripts/check-gosec-pin.sh, run in the Security Scanning job: it fails on a gosec version literal or a non-variable gosec ref in any tracked file, and on an install site that does not read .gosec-version. scripts/test-check-gosec-pin.sh covers both directions and asserts that the Makefile and the hook really read the file. Closes LeanerCloud#347 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Comment |
Resolve conflicts with LeanerCloud#1145 (scripts/run-gosec.sh, issue LeanerCloud#340), which moved the gosec install, rule set and module list into one shared script called by the pre-commit hook, `make security-scan-go`, CI and security-scan.sh, with its own GOSEC_VERSION="v2.28.0" literal. - scripts/gosec-hook.sh, scripts/security-scan.sh, ci.yml gosec step and .pre-commit-config.yaml: take main's run-gosec.sh delegation; only the comments now name .gosec-version as the version source. - scripts/run-gosec.sh: read and validate .gosec-version (the validation this branch had in gosec-hook.sh) instead of the literal, before Go runs or the cache is touched. The cache path is unchanged for v2.28.0. - scripts/test-run-gosec.sh: read the pin from .gosec-version. - scripts/test-check-gosec-pin.sh: the reader cases now run run-gosec.sh (directly and through the hook) with a stub go. - Makefile, pre-commit.yml, check-gosec-pin.sh: comments name run-gosec.sh as the reader. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
I merged Conflicts. All of them come from #1145 (
Follow-on edits needed so the merged tree keeps one pin:
Verification on
Nothing is left open on this PR. The known govulncheck failure (GO-2026-6809, fixed by #1236) is unrelated. |
Root cause
The gosec version was written out in several places that each had to be bumped by hand. On the base this PR started from, those were
ci.yml(go install ...gosec@v2.28.0),pre-commit.yml(an install step and a cache key), theMakefile(GOSEC_VERSION?=v2.28.0) andscripts/gosec-hook.sh(GOSEC_VERSION="2.28.0"). Comments inpre-commit.yml,.pre-commit-config.yamland the hook said it again. #1145 (merged since) moved the CI, hook andmake security-scan-goinstalls intoscripts/run-gosec.sh, which still kept its ownGOSEC_VERSION="v2.28.0"next to the Makefile'sinstall-dev-toolspin andpre-commit.yml's. All of them agree on v2.28.0 today, but a bump that misses one puts local scans and the CI scan that uploads to GitHub Security on different gosec versions. Nothing checked that they agree.The issue also lists stale comments and a dead install step. Both still exist on current main.
Fix
The version stays at v2.28.0. All pins already agreed, so this PR doesn't bump it.
.gosec-version(new, one line:v2.28.0) is now the only place the version is written. It follows thego-version-file: go.modidea, but as a plain file because gosec isn't a module dependency. It is read by:scripts/run-gosec.sh(from ci(gosec): run one rule set from a shared script in the hook, Makefile and CI #1145), which theci.ymlgosec step, the pre-commit hook,make security-scan-goandscripts/security-scan.shall call. It reads and validates the file instead of itsGOSEC_VERSIONliteral. A missing file, or one that isn't exactlyvMAJOR.MINOR.PATCH, exits 2 beforegoruns or the cache is touched. The cache path (~/.cache/gosec/v2.28.0-<go version>/gosec) is unchanged, so existing caches are reused, not reinstalled.Makefile:GOSEC_VERSION?=$(shell cat …/.gosec-version)forinstall-dev-tools. The path is resolved from the Makefile's own location, andmake GOSEC_VERSION=… install-dev-toolsstill overrides it.scripts/test-run-gosec.sh(from ci(gosec): run one rule set from a shared script in the hook, Makefile and CI #1145) reads the pin for its fake gosec from.gosec-versioninstead ofsed-ing it out ofrun-gosec.sh.pre-commit.yml:Install gosecstep is deleted, and gosec is dropped from the tool-cache key and name. Thegosechook isSKIPped in that job, and the hook installs its own copy under~/.cache/gosecthroughrun-gosec.shanyway, so~/go/bin/gosecnever ran even before the SKIP. A comment there records why gosec isn't installed.securego/gosecAction" is gone with the step..gosec-versioninstead of restatingv2.28.0.Makefile: the stale comment no longer claims sync withdatabase-migration.yml, which pins none of these tools.Comments in
ci.yml,.pre-commit-config.yaml,gosec-hook.shandsecurity-scan.shname.gosec-versionas the version source.Guard:
scripts/check-gosec-pin.sh(new). It runs as a step in the existingsecurity-scanjob, right after Set up Go. The step usesalways()and only needs checkout, so a finding doesn't skip the scanners. It is not a new job, soci-successneeds:is untouched. It runsgit grepover every tracked text file, not a list of known sites, so a new workflow or script is covered automatically. It fails on:.gosec-versionmissing, untracked, or not exactlyvMAJOR.MINOR.PATCH. That rejects2.28.0,v2.28,latest, empty, two lines, CRLF and trailing comments.GOSEC_VERSION=/?=/:assignments, cache keys, cache paths, image tags, ago.modrequirement, and prose likeruns gosec v2.28.0. Prose counts because a restated version goes stale on the next bump.gosec@latest,securego/gosec@<sha>(Action).securego/gosec/v2/cmd/gosec@, so continuedgo install \lines count) in a file that never mentions.gosec-version. At least one install site must exist, so an empty match can't pass.Exempt:
CHANGELOG.mdanddocs/audits/(historical records), and the guard and its self-test, which spell out the patterns. Exit codes: 0 clean, 1 findings, 2 usage error, the same scheme ascheck-gcp-secret-scope.sh.Self-test:
scripts/test-check-gosec-pin.sh(new, 43 cases, offline, a few seconds). It runs in the same CI step. Fixtures are throwaway git repos, run withGIT_CONFIG_GLOBAL=/dev/null. It covers:gosec-results.sarifand the codeql# v4.36.0comment.make -n install-dev-toolswith.gosec-versionset tov9.8.7must installgosec@v9.8.7. The realrun-gosec.sh, run directly and through the real hook with a stubgo, must callgo install …gosec@v9.8.7into its cache, and must stop with exit 2 without callinggoor creating the cache when the file is missing or malformed.Closes #347
Verification
Local shell, fixture and real-tool evidence on Linux (bash 5) after merging current
origin/main; macOS (bash 5 and/bin/bash3.2) was also covered before the merge. No Go code changed. The merged tree still builds andgo vets, andgo test ./cmd/server/(which parsesci.yml) passes.bash scripts/check-gosec-pin.sh:OK: gosec v2.28.0 is pinned only in .gosec-version; 2 install site(s) read it.The two sites arerun-gosec.shand the Makefile.bash scripts/test-check-gosec-pin.sh:43 passed, 0 failed.bash scripts/test-run-gosec.sh: all pass.origin/main(2f1dbca) with only the new check and test added,check-gosec-pin.shexited 1 with 21 findings and the self-test failed its reader and real-tree cases.bash scripts/gosec-hook.sh cmd/gen-permissions/main.goexits 0 and reuses the existing cached v2.28.0 binary, with no reinstall.make -n install-dev-toolsprintsgo install github.com/securego/gosec/v2/cmd/gosec@v2.28.0, andmake -n security-scan-goprints onlyscripts/run-gosec.sh.shellcheck0.11.0 on every touched script: clean.actionlint1.7.12 onci.ymlandpre-commit.yml: clean.git initwith an isolated HOME, afterscripts/setup-git-secrets.shand--register-aws, with the changed files tracked. The scan exits 0, and a planted fake key is flagged.Interaction with other PRs
scripts/run-gosec.shwith its ownGOSEC_VERSIONliteral. This PR's merge of main makesrun-gosec.shread.gosec-versioninstead, as the earlier version of this body anticipated.ci.ymland toci-successneeds:. This PR adds a step inside the existingsecurity-scanjob instead, so it doesn't touch that list.Out of scope
V=2.28.0…gosec@$V) isn't caught by the literal rule. Rule 4 still requires that file to mention.gosec-version.Maintainer: please mirror the issue's triage labels onto this PR:
priority/p3,severity/low,urgency/eventually,impact/internal,effort/xs,type/chore,triaged.🤖 Generated with Claude Code