A vulnerable dependency shows up in your build. How do you find out why it's there and upgrade it safely?
Question 437MediumGo 1.22 to 1.25
The commands used for dependency forensics:
govulncheck ./... # is the vulnerable symbol actually reachable?
go mod why -m golang.org/x/net # shortest import chain from your packages
go mod graph | grep 'golang.org/x/net@' # who requires which version
go list -m all # final build list (MVS result)
go list -m -u all # available upgrades
go list -m -json golang.org/x/net # details, incl. Replace/Deprecated
go get golang.org/x/net@v0.33.0 # raise the minimum
go mod tidy # prune unused, add missing, fix // indirect
go test ./... && git diff go.mod go.sum
Understand the output:
// indirectmeans that no package in your module imports it directly. You need it only because of MVS or graph pruning.go mod whycan say "main module does not need package ...". That happens when the dependency is only in the graph because of go.mod requirements, not imports.- Because of MVS, upgrading an indirect dependency simply means adding a higher minimum requirement to your go.mod. You don't have to wait for the intermediate library to release.
Gotchas: run go mod tidy in CI and fail on a diff. tidy considers all build tags and platforms, so it can add dependencies that your local build never uses.
More on Modules, Packages & Tooling
- Q435What does this print? Explain Go's package initialization order.
- Q436Go forbids import cycles. How do you detect and break them?
- Q438What is Profile-Guided Optimization (PGO) in Go and how do you use it in production?
- Q439How does Go ship behavior changes without breaking old code? Explain GODEBUG, the godebug directive and //go:debug. What does this print?
- Q440What are module graph pruning and lazy module loading (Go 1.17), and why did go.mod files get so much longer?
- Q441Explain the build cache, the module cache and test result caching. When does go test print "(cached)" and how do you defeat it?