给编程 Agent 接入实时漏洞情报
开源工具 opencraysec 通过 CLI 和 MCP 读取项目依赖及公开安全情报,并结合 Rust、Go 源码中的使用证据排列漏洞优先级。工具还提供修复命令规划、修复后重扫和历史结果核验。
AI 深度解读
AI 编程助手能改代码,却未必知道某个依赖今天刚被披露了漏洞。作者做的 opencraysec,就是给助手接上可更新的公开安全通告,再把扫描、升级建议、复查和修复记录串起来。
它值得看的地方,是让助手回答「这个依赖安全吗」时有证据可查。不过,查到已知漏洞、判断项目是否受影响、证明修复有效,是三件不同的事。原文既展示了结果,也交代了这些边界。
模型记不住今天的漏洞,就让它现场查
作者的核心判断是:模型训练数据有截止时间,安全通告却每天更新。仅凭模型记忆选版本,可能漏掉训练之后披露的问题。
opencraysec 用 Rust 编写,以单个静态二进制提供 CLI 和 MCP server,采用 MIT 许可证。作者称它不需要账号、API key,没有遥测,源码不会离开本机。预编译版本支持 Linux、macOS,Windows 通过 WSL2 使用。
下面的命令完成安装、按项目生态更新通告、扫描,以及接入 Claude:
curl -fsSL https://raw.githubusercontent.com/amgio38/opencraysec/main/scripts/install.sh | sh
opencraysec update --for . # advisories for the ecosystems this project uses
opencraysec scan .
claude mcp add opencraysec -- opencraysec mcp
重点是第二行:本地工具并不天然拥有最新情报,仍要执行更新,并检查报告里的数据时间。
它读取 Cargo、npm/yarn/pnpm、composer、go.mod、Python 的依赖文件,以及 GitHub Actions 固定的版本,结合 OSV、CISA 已知被利用漏洞清单、FIRST EPSS、MITRE CWE 和 NVD 等数据进行检查。排序先看恶意包,再看是否已被实际利用、被利用的可能性,最后看 CVSS 严重性评分。
漏洞分数只是处理顺序的一部分,正在被利用的问题更该先处理。
扫出多少问题,还要看依据是什么
原文实测使用 opencraysec 0.20261022.4,通告数据下载于 2026-10-22:crates.io 2,834 条、npm 229,905 条、Packagist 7,182 条、Go 9,582 条、PyPI 25,783 条。这些是记录量,不能直接当成检测准确率。
第一个案例是匿名的 Go + TypeScript 私有仓库,包含四个服务和一个前端。工具检查了 10 个锁文件、258 个包,耗时 2.4 秒,报告 115 个发现,其中 22 个为 critical。下面这条把版本、问题、使用位置和修复版本放在一起:
[HIGH 7.5] GHSA-fx2h-pf6j-xcff vite@5.4.21
vite: `server.fs.deny` bypass on Windows alternate paths
weakness: CWE-200, CWE-22
usage: your code imports it [admin-ui/vite.config.ts:4]
fix: 6.4.3 (admin-ui/package-lock.json)
要看的是 usage 行:它提供项目使用该包的线索,但不能单凭 import 就认定漏洞可被触发。原文将使用证据能力明确描述为面向 Rust 和 Go,示例却出现 TypeScript 配置文件的导入位置,具体支持范围没有解释清楚。
另一个案例是 250,000 行的 Rust workspace:4 个锁文件、856 个包,只报告一项 RUSTSEC-2026-0173,涉及 proc-macro-error2@2.0.1。原因是停止维护,并非已确认漏洞,也没有已发布的修复版本。
工具没有在作者代码里发现对它的导入,但它仍可能被其他依赖使用。作者明确说明:使用证据来自源码文本分析,不是调用图,可能漏掉动态使用,也看不到其他依赖内部的调用。not_found 只能理解成「你的代码没有导入它」。
修复闭环之外,助手配置也要扫描
opencraysec 把修复拆成三个动作:plan_fix 给出具体升级命令,不修改文件;verify_fix 重新扫描,确认哪些通告消失;record_fix 记录改了什么、为什么改、锁文件变化及执行命令。
其中一个约束很实用:如果此前没有对同一路径扫描并报告过问题,verify_fix 就拒绝宣称它已解决。这样能减少助手未经验证便汇报成功的情况。
但这里验证的是通告匹配结果的变化。升级后的功能兼容性,仍要靠项目自己的检查。
扫描范围还包括指导助手工作的配置。作者用一个 CLAUDE.md 和一个 .mcp.json 演示了三项疑似问题:向 URL 发送凭证或环境变量的 agent-exfiltrate,对应 CWE-200;MCP 包未固定精确版本的 agent-mcp-unpinned,对应 CWE-1357;要求忽略此前指令的 agent-override-instruction,对应 CWE-1427。
规则文件、hooks、自动任务和 skills 都可能让助手执行操作,因此也属于检查对象。scan_agent_config 会寻找注入指令、不可见字符、下载并运行代码的命令、未固定版本的包和秘密信息,并标注 CWE 与对应的 OWASP 条目;服务或 skill 启动的 MCP 包也会检查通告和恶意包数据。
不过,scan-code 和 scan-agent-config 依赖小型规则包做模式匹配,所有命中都标记为 suspected,需要人工读相关代码路径。
我的判断
我认同它把安全判断从模型记忆转向可更新数据,也认同「先扫描,再修复,再复查」的流程。相较于人手动跑扫描器,MCP 的价值是让这些步骤进入同一段编程对话。
但作者没有提供与其他依赖扫描工具的对照数据,也没有给出误报率、漏报率或团队效率变化。2.4 秒属于单个仓库的实测,不能据此推断普遍性能。「导入了包就优先处理」也是实用线索,并不等于完整的风险判定。
没有发现已知通告,不能写成项目已经安全。
原文还列出几个实际限制:requirements.txt 没有精确 == 固定版本的条目无法匹配;活动日志尚未轮转。遇到缺少锁文件、锁文件不可读或缺少对应生态通告数据等不完整结果时,工具会明确报告;配合 --fail-on,退出码为 3,避免 CI 在没查到东西时误判通过。
能拿来做什么
- 在前端或 Node 项目里,让助手选择依赖版本前先更新通告并扫描锁文件,把数据时间和扫描范围一起保留。
- 将
plan_fix、执行升级、verify_fix、项目测试和record_fix串成固定流程,要求助手分别交代漏洞复查结果与功能验证结果。 - 把
CLAUDE.md、.mcp.json、hooks 和 skills 纳入代码审查,重点核对外发凭证、下载执行和未固定版本的命令,对suspected命中逐项确认。 - 接入 CI 时区分发现问题与扫描不完整,显式处理
--fail-on返回 3 的情况,避免把缺少数据当成检查通过。