go-dependency-audit

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Go Dependency Audit

Go依赖项审计

Every dependency you add is code you don't control but are responsible for. Audit ruthlessly.
你添加的每一个依赖都是你无法控制但需要负责的代码。请严格进行审计。

1. Vulnerability Scanning

1. 漏洞扫描

govulncheck (official Go tool):

govulncheck(官方Go工具):

bash
undefined
bash
undefined

Install

Install

go install golang.org/x/vuln/cmd/govulncheck@latest
go install golang.org/x/vuln/cmd/govulncheck@latest

Scan project

Scan project

govulncheck ./...
govulncheck ./...

Scan binary

Scan binary

govulncheck -mode=binary ./cmd/api-server

`govulncheck` checks against the Go vulnerability database and reports
only vulnerabilities that actually affect your code paths — not just
transitive deps you never call.

Run this in CI. No exceptions.
govulncheck -mode=binary ./cmd/api-server

`govulncheck`会对照Go漏洞数据库进行检查,仅报告实际影响你代码路径的漏洞——而非那些你从未调用的间接依赖的漏洞。

必须在CI中运行此工具,无例外。

Additional scanning:

额外扫描工具:

bash
undefined
bash
undefined

Nancy (Sonatype OSS Index)

Nancy(Sonatype OSS索引)

go list -json -deps ./... | nancy sleuth
go list -json -deps ./... | nancy sleuth

Trivy (container + deps)

Trivy(容器+依赖项扫描)

trivy fs --scanners vuln .
undefined
trivy fs --scanners vuln .
undefined

2. go.mod Hygiene

2. go.mod规范性检查

Check for unused dependencies:

检查未使用的依赖项:

bash
go mod tidy
git diff go.mod go.sum  # any changes = deps were stale
go mod tidy
MUST be run before every commit. Add to CI:
bash
go mod tidy
git diff --exit-code go.mod go.sum
bash
go mod tidy
git diff go.mod go.sum  # 有变更说明依赖已过时
go mod tidy
必须在每次提交前运行。添加到CI中:
bash
go mod tidy
git diff --exit-code go.mod go.sum

No replace directives in committed code:

提交的代码中禁止使用replace指令:

go
// ❌ Bad — committed replace directive
replace github.com/foo/bar => ../local-bar

// ✅ Acceptable — in monorepos with workspace
// go.work handles this instead
Exception: temporary replace for bug fixes with a comment and linked issue:
go
// TODO(#1234): remove after upstream merges fix
replace github.com/foo/bar => github.com/myorg/bar v0.0.0-fix
go
// ❌ 错误——提交了replace指令
replace github.com/foo/bar => ../local-bar

// ✅ 可接受——在单体仓库中使用workspace
// 由go.work来处理
例外情况:为修复临时bug添加replace指令,并附带注释和关联问题:
go
// TODO(#1234): 上游合并修复后移除
replace github.com/foo/bar => github.com/myorg/bar v0.0.0-fix

Verify checksums:

校验校验和:

bash
go mod verify
This confirms that downloaded modules match their expected checksums. Failures indicate supply-chain tampering.
bash
go mod verify
此命令会确认下载的模块与预期的校验和匹配。校验失败表示存在供应链篡改风险。

3. Dependency Evaluation Criteria

3. 依赖项评估标准

Before adding any dependency, evaluate:
CriterionCheck
MaintenanceLast commit < 6 months? Active issue responses?
PopularityStars/forks alone mean nothing. Usage in production projects matters.
LicenseCompatible with your project? MIT/Apache/BSD preferred.
SizeDoes it pull in 50 transitive deps for one function?
AlternativesCan you do this with stdlib in < 50 lines?
API stabilityIs it v1+? Does it follow semver? Frequent breaking changes?
Test coverageDoes the project have meaningful tests?
添加任何依赖项之前,请评估以下内容:
评估标准检查项
维护状态最后一次提交是否在6个月内?是否积极响应问题?
流行度仅星标/分叉数无意义,生产项目中的实际使用情况才重要。
许可证是否与你的项目兼容?优先选择MIT/Apache/BSD许可证。
体积是否为了一个功能引入了50个间接依赖?
替代方案能否用标准库在50行代码内实现?
API稳定性是否为v1+版本?是否遵循语义化版本控制?是否频繁出现破坏性变更?
测试覆盖率项目是否有有意义的测试?

The stdlib question:

标准库优先原则:

Go's standard library is excellent. Before adding a dependency, ask: "Can I solve this with
net/http
,
encoding/json
,
database/sql
,
text/template
,
crypto/*
,
os/exec
, etc.?"
If the answer is yes and the code is < 100 lines, write it yourself.
Go的标准库非常优秀。添加依赖项之前,请自问:“我能否用
net/http
encoding/json
database/sql
text/template
crypto/*
os/exec
等标准库实现这个功能?”
如果答案是肯定的,且代码量少于100行,请自行实现。

4. Module Version Audit

4. 模块版本审计

List all dependencies with versions:

列出所有依赖项及其版本:

bash
go list -m all
bash
go list -m all

Check for available updates:

检查可用更新:

bash
go list -m -u all  # shows available updates
bash
go list -m -u all  # 显示可用更新

Upgrade strategy:

升级策略:

bash
undefined
bash
undefined

Update specific module

更新特定模块

go get github.com/foo/bar@latest
go get github.com/foo/bar@latest

Update all direct deps (minor/patch only)

更新所有直接依赖项(仅小版本/补丁版本)

go get -u ./...
go get -u ./...

Update all deps including major versions (dangerous)

更新所有依赖项,包括大版本(有风险)

go get -u -t ./...

ALWAYS run full test suite after updates:

```bash
go get github.com/foo/bar@v1.5.0
go mod tidy
go test -race ./...
go get -u -t ./...

更新后必须运行完整测试套件:

```bash
go get github.com/foo/bar@v1.5.0
go mod tidy
go test -race ./...

5. Transitive Dependency Analysis

5. 间接依赖分析

bash
undefined
bash
undefined

Why is this module in my dependency tree?

查看该模块为何出现在依赖树中?

go mod why github.com/some/transitive-dep
go mod why github.com/some/transitive-dep

Full dependency graph

完整依赖图

go mod graph
go mod graph

Visual dependency graph (with modgraphviz)

可视化依赖图(需modgraphviz)

go mod graph | modgraphviz | dot -Tpng -o deps.png

Watch for:
- 🔴 Transitive deps with known CVEs
- 🔴 Abandoned transitive deps (no commits in 2+ years)
- 🟡 Diamond dependency conflicts (two versions of same module)
- 🟡 Oversized transitive trees (a logging library pulling in gRPC)
go mod graph | modgraphviz | dot -Tpng -o deps.png

需要关注:
- 🔴 存在已知CVE的间接依赖
- 🔴 已废弃的间接依赖(2年以上无提交)
- 🟡 菱形依赖冲突(同一模块的两个版本)
- 🟡 过于庞大的间接依赖树(比如一个日志库引入了gRPC)

6. Go Version Management

6. Go版本管理

go
// go.mod
module github.com/myorg/myproject

go 1.22  // minimum Go version required
Rules:
  • Set
    go
    directive to the minimum version that supports features you use.
  • toolchain
    directive (Go 1.21+) pins the exact toolchain version.
  • Test against multiple Go versions in CI (at minimum: current and previous).
go
// go.mod
module github.com/myorg/myproject

go 1.22  // 所需的最低Go版本
规则:
  • go
    指令设置为支持你所用功能的最低版本。
  • toolchain
    指令(Go 1.21+)用于固定确切的工具链版本。
  • 在CI中针对多个Go版本进行测试(至少:当前版本和上一个版本)。

7. Recommended vs. Avoid

7. 推荐与避坑

Well-maintained, production-proven packages:

维护良好、经过生产验证的包:

DomainPackage
Logging
go.uber.org/zap
,
log/slog
(stdlib 1.21+)
HTTP Router
github.com/go-chi/chi
,
net/http
(1.22+ routing)
Config
github.com/caarlos0/env
,
github.com/spf13/viper
Testing
github.com/stretchr/testify
, stdlib
testing
Database
github.com/jackc/pgx
,
github.com/jmoiron/sqlx
Validation
github.com/go-playground/validator
UUID
github.com/google/uuid
Errors
go.uber.org/multierr
, stdlib
errors
(1.20+)
领域包名
日志
go.uber.org/zap
,
log/slog
(标准库1.21+)
HTTP路由
github.com/go-chi/chi
,
net/http
(1.22+路由功能)
配置
github.com/caarlos0/env
,
github.com/spf13/viper
测试
github.com/stretchr/testify
, 标准库
testing
数据库
github.com/jackc/pgx
,
github.com/jmoiron/sqlx
校验
github.com/go-playground/validator
UUID
github.com/google/uuid
错误处理
go.uber.org/multierr
, 标准库
errors
(1.20+)

Patterns to avoid:

需避免的模式:

  • ❌ Frameworks that take over
    main()
    (Go is not Java Spring)
  • ❌ ORMs that hide SQL (prefer
    sqlx
    or raw
    database/sql
    )
  • ❌ Code generators you don't understand
  • ❌ Packages with
    v0.x
    that have been v0 for 3+ years
  • ❌ 接管
    main()
    的框架(Go不是Java Spring)
  • ❌ 隐藏SQL的ORM(优先选择
    sqlx
    或原生
    database/sql
  • ❌ 你无法理解的代码生成器
  • ❌ 停留在v0.x版本超过3年的包

Audit Output Format

审计输出格式

undefined
undefined

Dependency Audit Report

依赖项审计报告

Module: github.com/myorg/myproject Go version: 1.22 Direct deps: N | Indirect deps: M
模块: github.com/myorg/myproject Go版本: 1.22 直接依赖数: N | 间接依赖数: M

🔴 Vulnerabilities

🔴 漏洞

  • CVE-XXXX-YYYY in github.com/foo/bar@v1.2.3 — upgrade to v1.2.5
  • CVE-XXXX-YYYY 存在于 github.com/foo/bar@v1.2.3 —— 升级至v1.2.5

🟡 Outdated Dependencies

🟡 过时依赖项

  • github.com/foo/bar v1.2.3 → v1.5.0 available (minor)
  • github.com/foo/bar v1.2.3 → 可用版本v1.5.0(小版本更新)

🟢 Observations

🟢 观察结果

  • go.mod is clean, no replace directives
  • All deps actively maintained
undefined
  • go.mod 干净,无replace指令
  • 所有依赖项均处于活跃维护状态
undefined