入门指南

依赖漏洞告警分级:三套来源、四档处置、五个静默改动

对照 GitHub Dependabot 与 npm audit 的公开文档,把告警拆成来源、可修性与影响面三个维度,写清自动修复什么时候会改掉父依赖或依赖范围,以及哪些噪音可以放心交给规则。

告警不是待办清单:先分来源,再判可修性,最后才决定谁看。

作者
AOPC 编辑部
发布
AOPC 编辑部
发布时间
更新
2026/10/26
核查
已复核
一个人在白板上把平台扫描、自动修复 PR 与本地审计三列告警画成同一条分流管线
经营者责任与 AI 执行层的关系

先看答案

适合谁
  • 一个人维护仓库、同时收到平台告警与本地审计结果的人
  • 已经打开自动修复、但不确定 PR 里改了什么的人
  • 想用规则压掉噪音、又怕误关真实风险的人
你会获得
先把三套来源对齐口径,再决定哪条今天修、哪条交给规则。
发布时间
实质更新
发布
AOPC 编辑部

60 秒结论

一分钟看懂这篇文章

告警不是待办清单:先分来源,再判可修性,最后才决定谁看。

人负责

  • 决定哪条今天修
  • 裁决依赖范围变更
  • 复核被规则关掉的告警

AI 负责

  • 归并三套来源
  • 比对 lock diff
  • 整理规则命中清单
  1. 分来源
  2. 判可修
  3. 定档位
  4. 留痕迹

直接答案

大多数「告警处理不完」的困境,不是告警太多,而是三套完全不同的东西被塞进了同一个列表:

  1. 平台扫描(Dependabot alerts)——某个 advisory 入库、或你的依赖图变了,就冒出一条;
  2. 自动修复尝试(Dependabot security updates)——它会对每一个有补丁的开放告警尝试开 PR,成功与否是另一回事;
  3. 本地审计(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 里需要时间」。也就是说,没有告警不等于没有漏洞,只等于「目前没有已审核、且进了库的记录」。

二、四档处置:把「修不修」变成「谁来决定」

下面四档是本文的处置建议,不是平台自带的分类。判据只有三个,按顺序问:

  1. 有补丁吗?(告警里会写 fixed version,没有就写「when available」)
  2. 它是直接依赖,还是被谁拖进来的?(决定改动会不会外溢)
  3. 它真的会在生产路径上跑吗?(开发依赖与运行时依赖要分开看)
档位 判据 动作 建议时限
今天修 有补丁 + 直接依赖 + 生产路径 合自动 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 规则来指定。

于是正确的开启顺序是:

  1. 先把规则配好(哪些自动关闭、哪些必须留给我看);
  2. 再决定安全更新是「全自动」还是「按规则挑选」;
  3. 最后调通知,只让需要人判断的那部分打扰你。

反过来(先开全自动、再想办法从 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 有没有进库。

六、三种误读

  1. 「开了安全更新就等于修完了。」 它只负责开 PR,升到包含补丁的最低版本;合并与否、测试过不过、要不要连带改父依赖,仍然是人(或你的 CI)的事。官方甚至给了反向建议:想挑着修,就别开它。
  2. 「告警数就是漏洞数。」 首次启用不补发存量、只对审核过的 advisory 触发、归档仓库不扫、SHA 固定的 action 不告警、npm audit 里 --omit 会把包从载荷里去掉。任何一个环节都会让数字偏离「真实漏洞数」,而且偏离方向不固定。
  3. 「自动关闭等于已修复。」 它只是一个 close reason(resolution:auto-dismiss),告警还在、可重开、可报表;依赖作用域从开发变生产时会自动重开。更极端的是 malware 预设规则:它会把「所有版本都被标为恶意」的告警自动关掉,官方明确警告——如果贡献者真的引入了一个所有版本都恶意的包,这条规则也会把它关掉。这条规则默认关闭,开之前要想清楚。

七、每周检查表

  • 默认分支是哪一个? 告警只扫默认分支,长期在别的分支上开发会看不到。
  • 通知到底发给了谁? 三个条件是否同时满足,还是只有一个空邮箱在收。
  • 首次启用后的存量过了一遍吗? 平台不会补发这批通知。
  • 规则命中清单本周看过吗? 尤其是「开发依赖」判定是否符合实际。
  • 安全更新是「全自动」还是「按规则挑选」? 两者不能同时成立。
  • lock 文件提交了吗? 没有 lock 时 npm audit 每次重建依赖树,结果可能每次不同。
  • CI 里的 --audit-level 被当成过滤器了吗? 它只改失败阈值,报告内容不变。
  • --force 出现在任何脚本里了吗? 它允许 SemVer 主版本升级,应单独走迁移流程。
  • 传递依赖改不动时,谁来决定改父依赖? 这个决定不能留给自动化。

来源

本文所有引用均来自下列公开页面,访问日期均为 2026-10-26,发布前逐条重新验证为 HTTP 200(GitHub 的旧路径已重定向到下列概念页与操作页,curl 跟随后记录最终 URL):

  1. Dependabot alerts – GitHub核查于 2026/10/26:扫描默认分支、两类触发条件、告警包含受影响文件/严重度/可用修复版本、通知的三个默认条件、首次启用不补发存量、规则先于通知、五项限制(不扫归档仓库、Actions 只对语义化版本、只处理审核过的 advisory、新漏洞入库需要时间)、告警可指派给人和 AI agent。
  2. Dependabot security updates – GitHub核查于 2026/10/26:对每个有补丁的开放告警尝试开 PR、只升到最小修复版本、修不动时在告警上报错、只对 manifest/lock 中的依赖触发、npm 可改父依赖或删除子依赖而其它生态不行、Actions 升到最小补丁版本、分组更新的边界、兼容性分数的来源、维护者不互动时临时暂停。
  3. Dependabot auto-triage rules – GitHub核查于 2026/10/26:规则可关闭/延后告警、指定哪些告警开 PR、先于通知生效;开发依赖低影响预设的判据与默认开启范围;malware 预设的误关风险;自定义规则的可用范围;自动关闭仍可检索、可重开,作用域变化与 advisory 元数据变化会触发自动重开;resolution:auto-dismiss 与审计日志。
  4. Viewing and updating Dependabot alerts – GitHub核查于 2026/10/26:按包/生态/manifest 过滤、批量关闭、dismissal reason 与 comment 进入时间线可用于审计、已修复告警不可重开而未修复的已关闭告警可重开。
  5. 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。

唯一主行动

把下一步变成可执行动作

查看产品维护与发布回滚工作流