Harden the checker against supply-chain attacks#20
Merged
Conversation
- Pass `--locked` to every operational cargo command in checks (`cargo clippy`, `cargo nextest run` in both unit and integration tests, `cargo +nightly udeps`). Without it cargo silently re-resolves `Cargo.lock` on metadata drift, opening a window for a fresh malicious version to land mid-build across 1028 transitive crates.
- Pin `apps/desktop/rust-toolchain.toml` channel from floating `stable` to `1.95.0`.
- Pin every tool install. `cargo install` now passes `--version` + `--locked` for `cargo-audit`, `cargo-deny`, `cargo-machete`, `cargo-udeps`, `cargo-nextest`. Every `EnsureGoTool` call replaced `@latest` with a specific version: `staticcheck@v0.7.0`, `nilaway@v0.0.0-20260515015210-fd187751154f`, `misspell@v0.3.4`, `gocyclo@v0.6.0`, `ineffassign@v0.2.0`, `deadcode@v0.45.0`. Closes the wave-1-2-class "the supply-chain tool itself gets trojaned" gap.
- New `workflows-hardening` check at `scripts/check/checks/desktop-workflows-hardening.go`. Scans `.github/workflows/*.{yml,yaml}` and fails on three classes the wave-4 (TanStack, May 2026) attack chained: tag/branch-pinned third-party actions (must be SHA-pinned, with `./...` local actions exempt), `pull_request_target` triggers, and workflow-scoped `id-token: write` (must be job-scoped). Cmdr passes today; the check is a regression guard. ~190 lines + ~200 lines of tests.
- New `govulncheck` check at `scripts/check/checks/scripts-go-govulncheck.go`. Runs `govulncheck@v1.3.0` against every `go.mod`. Mirrors `cargo-audit`'s role on the Rust side: static-analysis-based, low false-positive rate.
- Bump `.mise.toml` go from `1.25.7` to `1.25.10`. The `govulncheck` check found 7 reachable stdlib vulns in cmdr's tooling on its first run (CVE fixes in `net`, `crypto/tls`, `crypto/x509`, `net/url`, `archive/tar`, `os`). 1.25.10 is the latest patch in the 1.25 line.
- Update `scripts/check/CLAUDE.md` with four new Decision entries (the `--locked` rule, the tool-version-pin rule, the workflow-hardening check, the govulncheck check) and the apps/checks table now lists `govulncheck` and the new Security row.
The Rust hardening is mostly defense in depth; cmdr already has `cargo-audit`, `cargo-deny` (licenses/bans/sources), SHA-pinned actions, and `pnpm install --frozen-lockfile` in every CI workflow. The two new checks close the gaps surfaced in our pre-launch supply-chain review: no Go-side vuln scanner, no regression guard on the workflow hardening that's already in place.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the high-severity gaps surfaced in our pre-launch supply-chain review (Shai-Hulud waves 1-4). Cmdr is already well-positioned on the npm side (pnpm 11 deny-default, SHA-pinned actions, no
pull_request_target); this PR closes the Rust- and Go-side gaps and adds regression guards so the hardening can't silently regress on a future PR.--lockedto every operational cargo command in checks:cargo clippy,cargo nextest run(both unit and integration tests),cargo +nightly udeps. Without it cargo silently re-resolvesCargo.lockon metadata drift, opening a window for a fresh malicious version to land mid-build across 1028 transitive crates.apps/desktop/rust-toolchain.tomlchannel from floatingstableto1.95.0. A floating channel means a compromised rustc release would land transparently.cargo installnow passes--version+--lockedforcargo-audit,cargo-deny,cargo-machete,cargo-udeps,cargo-nextest. EveryEnsureGoToolcall replaced@latestwith a specific tag/pseudo-version:staticcheck@v0.7.0,nilaway@v0.0.0-20260515015210-fd187751154f,misspell@v0.3.4,gocyclo@v0.6.0,ineffassign@v0.2.0,deadcode@v0.45.0. Closes the wave-1-2-class "the supply-chain tool itself gets trojaned" gap.workflows-hardeningcheck atscripts/check/checks/desktop-workflows-hardening.go. Scans.github/workflows/*.{yml,yaml}and fails on three classes the wave-4 (TanStack, May 2026) attack chained: tag/branch-pinned third-party actions (must be SHA-pinned, with./...local actions exempt),pull_request_targettriggers, and workflow-scopedid-token: write(must be job-scoped). Cmdr passes today; the check is a regression guard. 192 lines of check + 199 lines of tests.govulncheckcheck atscripts/check/checks/scripts-go-govulncheck.go. Runsgovulncheck@v1.3.0against everygo.mod. Mirrorscargo-audit's role on the Rust side: static-analysis-based, so only flags vulns reachable from your code (low false positive rate)..mise.tomlGo from1.25.7to1.25.10. The newgovulncheckcheck found 7 reachable stdlib vulns in cmdr's tooling on its first run (CVE fixes innet,crypto/tls,crypto/x509,net/url,archive/tar,os). 1.25.10 is the latest patch in the 1.25 line.scripts/check/CLAUDE.mdwith four new Decision entries (the--lockedrule, the tool-version-pin rule, the workflow-hardening check, the govulncheck check) and the apps/checks table now listsgovulncheckand a new Security row.Test plan
./scripts/check.sh --check workflows-hardeningpasses against cmdr's 6 real workflows (all already SHA-pinned, nopull_request_target, no workflow-scopedid-token: write)../scripts/check.sh --check govulncheckpasses against all 7 Go modules under Go 1.25.10. Pre-bump it correctly failed on 7 reachable stdlib vulns, demonstrating the check works.scanWorkflowFilecover all three violation classes plus the negative cases (SHA-pinned accepted, local action exempt,pull_requestnotpull_request_target, job-scopedid-token: writeaccepted, comments ignored). All pass../scripts/check.sh --check gofmt --check go-vet --check staticcheck --check go-testsall pass.main; affected checks re-run green post-rebase.