安全清单
安全不是一项功能,而是贯穿开发的纪律。本页按"依赖 → 输入 → 注入 → Web → 认证 → 运行时"给出 Go 服务的核心安全实践,结尾附上线检查清单。
依赖安全:govulncheck
依赖漏洞是 Go 服务最现实的风险面。官方工具 govulncheck 扫描已知漏洞(CVE),且只报告真正被你的代码调用到的漏洞,误报极少:
配套纪律:依赖最小化(每加一个依赖都是加攻击面)、定期 go get -u 升级补丁版本、锁定关键依赖的版本变更评审。
输入:一切外部输入不可信
信任边界之内(你的代码)与之外(用户、第三方)之间,所有进入的数据都要校验:
三类高危输入场景:
- 路径穿越:用户输入拼进文件路径时,
../..可读任意文件。修复:filepath.Clean后校验仍在基准目录内,或直接拒绝含分隔符的输入。 - SSRF:接受用户提供的 URL 并出站请求时,攻击者可探测内网(
http://169.254.169.254/云凭证端点是经典目标)。修复:解析后校验 host 非内网段、禁止重定向跟随、出站走白名单。 - 正则输入:Go 的 RE2 引擎无回溯,天然免疫多数正则 DoS,但仍应限制输入长度。
注入防护
gosec(golangci-lint 中启用)会自动标记这两类问题。
Web 专项
Go 的 encoding/json 与 html/template 已规避大半 XSS(自动转义),剩余重点是响应控制:
要点:
- Cookie 会话必须设置
HttpOnly、Secure、SameSite=Lax,可同时防 XSS 窃取与 CSRF。 - CORS 是白名单机制,不是"允许所有来源的调试开关"。
- HTTPS 终止可在负载均衡/网关,服务自身跳过明文端口即可;需要 Go 直接终止 TLS 时用
autocert(Let's Encrypt 自动证书)。
认证与会话
实战项目的认证栈(bcrypt + JWT)之外,生产还需补齐:
密钥与配置
- 密钥只来自环境变量或密钥管理服务,代码/配置文件/日志中零硬编码(实战项目的 JWT_SECRET 即此模式)。
- 仓库接入秘密扫描(如
gitleaks)防止误提交;泄漏过的密钥立即轮换,删除提交不等于未泄漏。 - 日志脱敏:密码、令牌、证件号不入日志(slog 字段化日志天然便于过滤)。
运行时最小权限
- 容器以
nonroot运行、使用 distroless 无 shell 镜像(工程化)。 - 管理端点(
/debug/pprof、/metrics)只绑内网地址。 - 文件系统只读挂载 + 显式声明需要的写路径。
- 服务间调用用最小权限凭证,不共享超级账号。
上线安全检查清单
-
govulncheck ./...零高危,且已加入 CI - 所有外部输入经过校验(长度/格式/白名单)
- SQL 全参数化,
exec无 shell 拼接 - Cookie 三件套(HttpOnly/Secure/SameSite)与 CORS 白名单确认
- 登录接口有限流,错误信息不泄露用户存在性
- JWT 算法锁定、短有效期、密钥来自环境
- 日志无敏感字段,仓库有秘密扫描
- 容器 nonroot + distroless,管理端口未对公网开放
小结
- 依赖漏洞用
govulncheck常态化扫描,依赖面越窄越安全。 - 一切输入不可信:路径穿越与 SSRF 是 Go 服务两大特色风险。
- XSS/CSRF 优先交给框架与 Cookie 属性,CORS 严格白名单。
- 认证看生命周期(短令牌 + 限流 + 不泄露枚举面),运行时看最小权限。