入门指南
依赖漏洞告警分级:三套来源、四档处置、五个静默改动
对照 GitHub Dependabot 与 npm audit 的公开文档,把告警拆成来源、可修性与影响面三个维度,写清自动修复什么时候会改掉父依赖或依赖范围,以及哪些噪音可以放心交给规则。
告警不是待办清单:先分来源,再判可修性,最后才决定谁看。

先看答案
- 适合谁
- 一个人维护仓库、同时收到平台告警与本地审计结果的人
- 已经打开自动修复、但不确定 PR 里改了什么的人
- 想用规则压掉噪音、又怕误关真实风险的人
- 你会获得
- 先把三套来源对齐口径,再决定哪条今天修、哪条交给规则。
- 发布时间
- 实质更新
- 发布
- AOPC 编辑部
60 秒结论
一分钟看懂这篇文章
告警不是待办清单:先分来源,再判可修性,最后才决定谁看。
人负责
- 决定哪条今天修
- 裁决依赖范围变更
- 复核被规则关掉的告警
AI 负责
- 归并三套来源
- 比对 lock diff
- 整理规则命中清单
- 分来源
- 判可修
- 定档位
- 留痕迹
直接答案
大多数「告警处理不完」的困境,不是告警太多,而是三套完全不同的东西被塞进了同一个列表:
- 平台扫描(Dependabot alerts)——某个 advisory 入库、或你的依赖图变了,就冒出一条;
- 自动修复尝试(Dependabot security updates)——它会对每一个有补丁的开放告警尝试开 PR,成功与否是另一回事;
- 本地审计(
npm audit)——你在自己机器或 CI 上主动跑的一次快照,口径又不一样。
三者的数量不能互相抵消,也不能互相证明。一个人维护仓库时,真正的目标不是把数字清零,而是每天只处理必须由人判断的那几条,其余交给规则、分组和通知设置。
所以顺序应该是:先分来源 → 再判可修性 → 最后才定档位。反过来做——先按严重度排序、从上往下修——你会把时间花在「改不动」和「改了也没用」的条目上。
一、三套来源各自看到什么、看不到什么
| 来源 | 什么时候产生 | 覆盖范围 | 天生看不到什么 |
|---|---|---|---|
| Dependabot alerts | 新漏洞加入 GitHub Advisory Database;或依赖图变化(推了改包的提交) | 仓库默认分支上的完整依赖图 | 未经 GitHub 审核的 advisory、归档仓库、用 SHA 固定的 Actions |
| Dependabot security updates | 有开放告警、且存在可用补丁 | 只在 manifest 或 lock 文件里显式声明的依赖 | 非 npm 生态中「必须同时改父依赖」的传递依赖 |
npm audit |
你主动跑(本地或 CI) | 提交给 registry 的那份依赖树 | 被 --omit 排除的包、没有 version 字段的包 |
| auto-triage 规则 | 每条告警创建时先过一遍 | 命中的告警被自动关闭或延后 | 规则写错时,它不会告诉你「本来该报」 |
这张表看着平淡,但它解释了三种最常见的困惑:
- 「为什么告警比我在本地跑出来的多?」 因为平台看的是完整依赖图,本地审计只看你这次提交的树;平台还会因为 advisory 入库而新增告警,哪怕你一行代码都没改。
- 「为什么有一条告警一直没有 PR?」 因为安全更新只对 manifest/lock 里声明的依赖触发——「图里有、但没写进清单」的依赖会有告警,却不会自动修。非 npm 生态里,如果修传递依赖必须连带改父依赖,Dependabot 也改不动,只会在告警上留一条错误。
- 「为什么归档仓库没有告警?」 官方明确写了:Dependabot 不扫描归档仓库。同理,GitHub Actions 只对使用语义化版本的 action 生成告警,用 SHA 固定版本的不在其列。
还有一个容易忽略的覆盖缺口:平台只对经 GitHub 审核的 advisory 触发告警,而「新漏洞出现在 Advisory Database 里需要时间」。也就是说,没有告警不等于没有漏洞,只等于「目前没有已审核、且进了库的记录」。
二、四档处置:把「修不修」变成「谁来决定」
下面四档是本文的处置建议,不是平台自带的分类。判据只有三个,按顺序问:
- 有补丁吗?(告警里会写 fixed version,没有就写「when available」)
- 它是直接依赖,还是被谁拖进来的?(决定改动会不会外溢)
- 它真的会在生产路径上跑吗?(开发依赖与运行时依赖要分开看)
| 档位 | 判据 | 动作 | 建议时限 |
|---|---|---|---|
| 今天修 | 有补丁 + 直接依赖 + 生产路径 | 合自动 PR 或手动升到修复版,跑一遍测试 | 当天 |
| 本周排 | 有补丁 + 传递依赖;或改动会外溢到父依赖 | 看 lock diff,必要时手动改父依赖或换包 | 本周内 |
| 规则忽略 | 仅开发作用域 + 低影响类别(资源管理、逻辑、信息泄露这类) | 交给 auto-triage 规则自动关闭,保留可检索记录 | 立即生效,按周复核 |
| 不适用 | 归档仓库、SHA 固定 action、advisory 未审核 | 记录在案,不要当成「已处理」 | 每季度重看 |
第三档值得展开,因为它是唯一能真正把噪音降下来的档位。GitHub 有一个预设规则 Dismiss low impact issues for development-scoped dependencies:它自动关闭 npm 开发依赖里的特定类型漏洞——官方给的判据是「在开发者环境(非生产、非运行时)不太可能被利用」「可能涉及资源管理、编程与逻辑、信息泄露」「最坏影响有限,比如构建变慢、测试跑得久」「不代表生产环境有问题」。这条规则在公开仓库默认开启,私有仓库需要主动选择加入。
但预设不是免费午餐,官方自己写了两条边界:
- 它的判据是 CWE 类别 + 依赖作用域,不是你的调用路径;
- 它只覆盖 npm 生态的开发依赖,别的生态、别的依赖类型不在内。
还有一条更关键的机制:自动关闭的告警会在元数据变化时被自动重新打开,官方举的例子就是「依赖作用域从开发改成生产」。所以「被规则关掉」不是终点,而是「等它变成生产依赖时再叫我」——这也意味着你不需要每周人工重扫一遍已关闭列表,但需要保证作用域标注是准的。
另外,关闭动作本身要留痕。告警支持填写 dismissal comment,评论会进入告警时间线,官方明确说它可以「作为审计与报告时的理由」。而且:已修复的告警不能重开,已 dismiss 的未修复告警可以重开——所以「先关掉、以后再说」在操作上是可逆的,前提是你写了理由。
三、五个静默改动:自动修复到底改了什么
「开启自动修复」听起来像开了一个开关,实际上它改的是你的依赖树。以下五件事,官方文档都写了,但没有一件会弹窗提醒你。
① 只升到「包含补丁的最低版本」。 官方原文是升到 “the minimum version that includes the patch”。这不是「升到最新」,所以你修完这条 advisory 之后,很可能离下一条只差一个小版本。对一人公司来说这通常是对的(改动最小),但要接受「同一个包会反复出现」的节奏,而不是每次都觉得「怎么又来了」。
② npm 生态会连带改父依赖,甚至删掉子依赖。 官方写得很直白:对 npm,Dependabot 会把显式声明的依赖升到安全版本,「即使这意味着更新父依赖,甚至移除父依赖不再需要的子依赖」。其它生态则相反——如果修传递依赖必须同时改父依赖,Dependabot 改不动。所以同一个「高危」标签,在 npm 项目里可能是一个大 lock diff,在别的生态里可能是一条永远修不掉的错误。
③ 它只对 manifest/lock 里声明的依赖动手。 前面提过,这里再强调一次方向:告警覆盖完整依赖图,修复只覆盖清单里的依赖。这意味着「图里更深的那一层」需要你主动把它提成直接依赖,或者等上游发版。
④ npm audit fix --force 才允许改依赖范围。 npm 文档的说法是:当漏洞链一路延伸到根项目、且不改依赖范围就修不了时,npm audit fix 需要 --force 才会应用修复;不带 --force 时,只把包升到「没有 advisory 或 meta-vulnerability」的版本。而 --force 的语义就是「安装 SemVer 主版本更新到顶层依赖」——这正是上一篇《第三方 API 版本升级》里建议单独走迁移流程的那类改动。把它写进任何自动化脚本,等于把主版本升级交给了一个不会读 changelog 的进程。
⑤ 「兼容性分数」不是你自己的测试结果。 安全更新的 PR 上可能出现一个 compatibility score,官方定义是:用其它公开仓库里同一个安全更新的 CI 运行结果算出的通过百分比。它是有用的参考,但它回答的是「别人升这个版本时测试过不过」,不是「你的项目升了会不会坏」。
还有一条不算改动、但会影响你判断的机制:当维护者长期不与 Dependabot 的 PR 互动时,它会临时暂停更新并通知你。所以「突然没有 PR 了」有两种可能——没有新告警,或者自动化被暂停了。这两种情况的处置完全相反,别混。
四、压噪音:三个开关和一条不能反的顺序
开关一:通知对象。 默认只发给「同时满足」三个条件的人:对仓库有 write/maintain/admin 权限、正在 watch 这个仓库、且开启了安全告警通知。一个人维护时这条通常不是问题,但如果你用组织账号、或让一个不常看的邮箱接收,等于没有通知。官方也给了一个更省心的选项:每周摘要,或者干脆关掉通知、只保留告警列表。
开关二:首次启用不补发历史。 官方明确写了:首次启用 Dependabot 时,GitHub 不会为仓库里已存在的所有脆弱依赖发通知,只通知启用之后新发现的。所以「我刚打开,怎么这么安静」是正常现象——存量需要你自己去列表里过一遍。
开关三:规则先于通知。 自动分类规则在通知发出之前生效,被自动关闭的告警不会发通知。这既是降噪的原理,也是风险所在:规则写宽了,你会静默地少看到一类告警。官方的补救是这些告警仍然可检索、可报表、可重开,并且关闭原因标记为 resolution:auto-dismiss,相关活动会进 webhook、REST/GraphQL API 和审计日志。
然后是那条顺序。安全更新的行为是「对每一个有补丁的开放告警尝试开 PR」,官方在同一个 Note 里给了替代方案:如果你想自己挑哪些告警开 PR,就应该让安全更新保持关闭,改用 auto-triage 规则来指定。
于是正确的开启顺序是:
- 先把规则配好(哪些自动关闭、哪些必须留给我看);
- 再决定安全更新是「全自动」还是「按规则挑选」;
- 最后调通知,只让需要人判断的那部分打扰你。
反过来(先开全自动、再想办法从 PR 洪水里逃出来)会导致两个后果:一是你开始无差别关闭 PR,二是规则永远追不上已经开出来的 PR。
关于分组,还有两条边界值得记住:分组更新按生态合并,不会跨生态,也不会把安全更新和版本更新合到一个 PR 里;如果你在 dependabot.yml 里写了分组规则,那么「跨未配置目录」的分组只有在组织/仓库级别也开启分组时才生效。
五、一人公司的一周节奏(可照抄)
- 周一,15 分钟:只看新告警。按包名、生态、manifest 过滤,先分「直接依赖/传递依赖」,不要先按严重度。
- 当天:落在「今天修」档的,合 PR 或手动升,跑测试。合完之后对应的告警会自动关闭——这是官方写明的唯一一处
dependabot.yml与安全告警的交互。 - 周三,30 分钟:处理「本周排」档。npm 项目先跑
npm audit fix --dry-run --json看它打算做什么,再决定要不要真跑;涉及父依赖变更的,当成一次小迁移。 - 周五,10 分钟:翻一遍本周被规则自动关闭的告警。重点看两类:作用域标错的(本该是生产依赖却标成了开发),和预设没覆盖到但你觉得该看的类别。
- 每月:跑一次
npm audit(不加--omit/--production,否则被排除的包根本不进审计载荷),再跑一次npm audit signatures校验 registry 签名与 provenance 声明。后者官方提醒「往往需要比 Node 自带的更新的 npm CLI」。 - 每季度:重看「不适用」档——归档仓库要不要恢复、SHA 固定的 action 要不要改成语义化版本、未审核的 advisory 有没有进库。
六、三种误读
- 「开了安全更新就等于修完了。」 它只负责开 PR,升到包含补丁的最低版本;合并与否、测试过不过、要不要连带改父依赖,仍然是人(或你的 CI)的事。官方甚至给了反向建议:想挑着修,就别开它。
- 「告警数就是漏洞数。」 首次启用不补发存量、只对审核过的 advisory 触发、归档仓库不扫、SHA 固定的 action 不告警、
npm audit里--omit会把包从载荷里去掉。任何一个环节都会让数字偏离「真实漏洞数」,而且偏离方向不固定。 - 「自动关闭等于已修复。」 它只是一个 close reason(
resolution:auto-dismiss),告警还在、可重开、可报表;依赖作用域从开发变生产时会自动重开。更极端的是 malware 预设规则:它会把「所有版本都被标为恶意」的告警自动关掉,官方明确警告——如果贡献者真的引入了一个所有版本都恶意的包,这条规则也会把它关掉。这条规则默认关闭,开之前要想清楚。
七、每周检查表
- 默认分支是哪一个? 告警只扫默认分支,长期在别的分支上开发会看不到。
- 通知到底发给了谁? 三个条件是否同时满足,还是只有一个空邮箱在收。
- 首次启用后的存量过了一遍吗? 平台不会补发这批通知。
- 规则命中清单本周看过吗? 尤其是「开发依赖」判定是否符合实际。
- 安全更新是「全自动」还是「按规则挑选」? 两者不能同时成立。
- lock 文件提交了吗? 没有 lock 时
npm audit每次重建依赖树,结果可能每次不同。 - CI 里的
--audit-level被当成过滤器了吗? 它只改失败阈值,报告内容不变。 -
--force出现在任何脚本里了吗? 它允许 SemVer 主版本升级,应单独走迁移流程。 - 传递依赖改不动时,谁来决定改父依赖? 这个决定不能留给自动化。
来源
本文所有引用均来自下列公开页面,访问日期均为 2026-10-26,发布前逐条重新验证为 HTTP 200(GitHub 的旧路径已重定向到下列概念页与操作页,curl 跟随后记录最终 URL):
- Dependabot alerts – GitHub核查于 2026/10/26:扫描默认分支、两类触发条件、告警包含受影响文件/严重度/可用修复版本、通知的三个默认条件、首次启用不补发存量、规则先于通知、五项限制(不扫归档仓库、Actions 只对语义化版本、只处理审核过的 advisory、新漏洞入库需要时间)、告警可指派给人和 AI agent。
- Dependabot security updates – GitHub核查于 2026/10/26:对每个有补丁的开放告警尝试开 PR、只升到最小修复版本、修不动时在告警上报错、只对 manifest/lock 中的依赖触发、npm 可改父依赖或删除子依赖而其它生态不行、Actions 升到最小补丁版本、分组更新的边界、兼容性分数的来源、维护者不互动时临时暂停。
- Dependabot auto-triage rules – GitHub核查于 2026/10/26:规则可关闭/延后告警、指定哪些告警开 PR、先于通知生效;开发依赖低影响预设的判据与默认开启范围;malware 预设的误关风险;自定义规则的可用范围;自动关闭仍可检索、可重开,作用域变化与 advisory 元数据变化会触发自动重开;
resolution:auto-dismiss与审计日志。 - Viewing and updating Dependabot alerts – GitHub核查于 2026/10/26:按包/生态/manifest 过滤、批量关闭、dismissal reason 与 comment 进入时间线可用于审计、已修复告警不可重开而未修复的已关闭告警可重开。
- npm-audit – npm Docs核查于 2026/10/26:默认发现漏洞即非零退出、
--audit-level只改失败阈值不过滤报告、npm audit fix底层跑完整npm install、部分漏洞无法自动修、--force才允许改依赖范围、默认需要 lock 文件而--no-package-lock结果可能每次不同、Bulk Advisory 载荷会因--omit排除包、meta-vulnerability 与缓存、audit signatures校验签名与 provenance 且常需比 Node 自带更新的 npm。