CVE 跟踪
跟踪影响依赖的 CVE、映射到你的暴露、验证修复落入锁文件。
为什么
依赖中 CVE 是你软件中漏洞 — 你发那代码、以你权限运行、你对修复负责。但你不能修你不跟踪的,且 CVE 洪流(每年数千)使手动跟踪不可能。自动跟踪 — CI 中 OSV-Scanner / Snyk / GitHub Dependabot 告警 — 把洪流转分诊清单:哪些 CVE 影响你确切锁文件、哪些在你配置可利用、哪些已在你装版本修。关键是把每 CVE 映射到你实际暴露,因树中多数 CVE 不影响你(错代码路径、你配置缓解、传递已补)。跟踪 + 暴露映射是使 CVE 响应可管的方式。
何时使用
CI 中持续 — 每 PR 和每日构建扫。48 小时内分诊新告警。
如何做
1. CI 自动扫:每 PR + 每日计划跑 OSV-Scanner 或 Snyk 2. 每告警映射暴露:你代码调脆弱函数?你配置满足利用条件? 3. 分诊:可利用 -> P0/P1(现在修)| 不可利用但有修复 -> P2(下发布修)| 不适用 -> 带书面理由驳回 4. 升依赖到修复版本修;验证修复在锁文件(npm ci 用新版本) 5. 若暂无修复:应用变通(如禁受影响功能)或钉安全传递版本 6. 跟踪 CVE 仪表盘:CVE、依赖、严重度、我们配置可利用?、修复版本、状态 7. 季度审驳回 CVE — 配置变时"不适用"可变适用
示例
# CI CVE 扫(GitHub Actions,每 PR + 每日)
on: [pull_request, schedule: [{ cron: '0 6 * * *' }]]
jobs:
cve-scan:
steps:
- run: npx @google/osv-scanner --lockfile package-lock.json --format json > osv.json
- run: node scripts/triage-cves.js osv.json # 映射暴露、赋优先级
# triage-cves.js(暴露映射)
for (const vuln of osvResults) {
const isCalled = await grepCodebase(vuln.affectedFunction);
const isExploitable = isCalled && configMeets(vuln.exploitCondition);
vuln.priority = isExploitable ? 'P0' : 'P2';
vuln.reason = isExploitable ? '可利用' : `未调 / 被 ${config} 缓解`;
}
# CVE 仪表盘
| CVE | 依赖 | CVSS | 调用? | 可利用? | 修复版本 | 状态 |
|----------------|-----------|------|---------|--------------|----------|--------|
| CVE-2024-1234 | lodash | 7.5 | 是 | 是 | 4.17.21 | 已修 |
| CVE-2024-5678 | minimist | 5.3 | 否 | 否 | 1.2.6 | 驳回 |
| CVE-2024-9999 | express | 9.8 | 是 | 是 | (无) | 变通 |
# 修(升依赖)
npm install [email protected]
# 验证锁文件有修复版本
npm ls lodash # -> 4.17.21常见问题
- ⚠扫但不映射暴露 — 你修 47 CVE,40 不影响你代码路径,浪费努力并发不需升级。
- ⚠无书面理由驳回 CVE — 配置变时 CVE 变适用且无人记为何驳回。
- ⚠package.json 修依赖但锁文件仍旧版本 — npm install 没跑,修复未达生产。
最佳实践
- ✓修前把每 CVE 映射到你实际暴露(函数调?利用条件满足?)— 树中多数 CVE 不影响你。
- ✓每驳回 CVE 记书面理由 — "因 X 不适用"使未来审查者配置变时能复查。
- ✓升后验证修复在锁文件(npm ls <依赖>)— package.json 改无锁文件更新永不达生产。