安全扫描 是做什么的?
在一个问题上给出可靠的回答:这些项目是否暴露于当前值得关注的依赖项漏洞?“当前值得关注”意味着要么已被目录化且可触及,要么是正在活跃发生但尚未完全传播到审计数据库中的事件。
相对于单纯的 npm audit,其额外价值在于研究层。公告数据库滞后于披露,恶意包事件通常通过取消发布来处理(没有可查询的公告)。因此,本扫描将确定性工具与关于当前活跃利用的实时研究相结合,并直接检查锁文件中的这些名称——这是最快的可靠信号,而任何审计工具都无法提供。
默认只读:仅调查和报告。只提出修复建议;未经用户许可不要应用版本升级(它们可能破坏构建)。
何时使用
- “调查安全问题”/“检查依赖项漏洞”/“运行安全扫描”。
- “我们是否受到 <某个 CVE、GHSA 或包安全事件> 的影响?”——用户读到某些信息后想了解自己的暴露情况。
- 定期检查(结合
schedule技能进行周期性云端扫描——见末尾)。
第一步——范围
决定扫描范围。默认扫描当前项目;如果用户措辞宽泛(“我们的项目”、“所有内容”、“整个集群”),则提供多仓库扫描。
- 当前项目:你所在的仓库。
- 多仓库:枚举当前仓库旁边的兄弟仓库——即当前 Git 根目录的父目录(通常是
~/projects/*/或~/src/*/)。在遍历前与用户确认目录,而不是直接假设;错误的猜测会浪费大量扫描时间。对于每个仓库,通过清单文件检测生态系统(见下),依次扫描,按项目报告。
第二步——检测生态系统并定位锁文件
每个项目中,如果存在锁文件,则视为该生态系统存在:
| 生态系统 | 清单/锁文件 | 通常位置 |
|---|---|---|
| npm | package-lock.json | frontend/ 或仓库根目录 |
| Go | go.mod / go.sum | backend/ 或仓库根目录 |
| Python | poetry.lock、requirements.txt、uv.lock | 仓库根目录 |
| Swift/SPM | Package.resolved | ios/ 或 .xcodeproj 内 |
扫描的是锁文件——而不是清单文件——因为它固定了实际安装的确切传递版本。
第三步——确定性基线(按生态系统)
运行生态系统自身的工具。这些工具会捕获所有已在公告数据库中的漏洞。优先选择具有可达性分析的工具(它们只报告代码实际可以触及的漏洞)。
- npm:
cd <dir> && npm audit --omit=dev --audit-level=high(针对交付给用户的内容)和普通的npm audit(全部,仅作参考)。无可达性分析——会过度报告;生产环境发现需加权。 - Go:
govulncheck ./...——包含可达性分析(仅标记已调用代码中的漏洞);一次性安装:go install golang.org/x/vuln/cmd/govulncheck@latest。这些工具中的黄金标准。 - Python:
pip-audit(或pip-audit -r requirements.txt)。 - 任何生态系统,或缺少工具时:
osv-scanner针对锁文件运行,通过容器运行以避免安装步骤:<runtime> run --rm -v "$PWD:/src:ro" ghcr.io/google/osv-scanner:latest scan --lockfile=/src/<lockfile>。 数据库最广泛;是 Swift/SPM 的备选方案,因为其第一方工具较弱。
捕获每个工具的报告内容。区分生产/可触及和开发/构建时的漏洞——构建工具中从未交付的高危漏洞与运行时依赖中的高危漏洞不是同一回事。
第四步——研究活跃威胁态势(增值步骤)
这是纯审计无法做到的。使用 WebSearch / WebFetch 查找当前活跃的威胁,然后将名称带回第五步。
- 项目生态系统中的近期供应链事件:搜索近期 npm/PyPI/Go 入侵和恶意软件活动;检查 GitHub 公告数据库 (github.com/advisories) 和 OSV (osv.dev) 是否包含第二步发现的包的最新条目。
- 如果用户指定了特定的 CVE / GHSA / 事件,获取权威公告并提取确切的受影响包名称和版本范围——这些将用于与锁文件匹配。
- 优先采用主要来源(公告、维护者公告、注册表安全通知)而不是聚合器标题;对于未确认的信息需注明。
保持时效性:为每个声明标注日期,并说明你的研究时间窗口(例如“过去约 8 周内披露的活跃事件”)。
第五步——直接对照锁文件交叉引用名称
对于第四步中发现的每个包,不要等待审计工具——直接检查锁文件中的固定树。这是领先指标步骤:
# npm
cd <dir> && npm ls <package>
grep -n '"<package>"' package-lock.json
# Go
grep -n '<module-path>' go.sum
# Python
grep -in '<package>' poetry.lock requirements.txt uv.lock 2>/dev/null
# Swift
grep -rn '<package>' --include=Package.resolved .
然后将固定版本与公告的受影响范围进行对比。每个名称有三种结果:暴露(存在且在范围内)、安全(不存在,或存在但不在范围内)、不确定(传递版本无法完全解析——需进一步调查或标记)。
第六步——报告
每个项目,以结论开头,然后附上证据:
- 暴露——包、固定版本、公告/事件、是否为生产可触及、以及具体的补救措施(目标版本升级;绝不使用盲目的
npm audit fix)。如果已安装的版本可能已被入侵,需注意其 postinstall 脚本可能已经运行——这是ignore-scripts默认设置重要的主要原因。 - 安全——经过检查的研究过的活跃威胁均不存在。说明检查的内容,使“安全”具有实际意义。
- 不确定/未覆盖——工具较弱的生态系统(Swift)、未解析的传递依赖、或研究无法确认范围的内容。指出差距而不是暗示完全覆盖。
不要暗示你已发现所有内容。明确说明时间窗口和实际扫描的生态系统。
组合使用
- 周期性扫描:将本技能的过程交给
schedule技能,进行每周云端运行以检查所有仓库,这样新事件能在几天内被捕获,而不是等到有人想起来检查。 - 发布或推送前:运行一次范围限定于单个项目的扫描。如果项目有预推送步骤(如
make audit/make secret-scan),它可以与之一同使用。
备注
- 审计工具是滞后指标;新闻和本技能的第四步是领先指标。当两者不一致时——研究表明某个包已遭入侵但工具静默——应信任直接的锁文件检查并将其视为实时事件。
npm audit报告的是公告严重级别,而非你的可利用性(无可达性分析)——它会过度报告。govulncheck相反,是在生态系统提供时可优先选择的模型。- 本技能回答的是暴露问题。补救措施(版本升级、锁定、为特定脚本异常执行
npm rebuild)是独立的、用户批准的步骤——提出修复方案,不要未经提示就应用它。