Go

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:

  • // indirect means that no package in your module imports it directly. You need it only because of MVS or graph pruning.
  • go mod why can 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

All 36 Modules, Packages & Tooling questions