2023年,谷歌开源安全团队处理了超过1.2万份漏洞报告。最终确认有效的不到3000份——四分之三的精力,砸进了噪音里。
这个数字来自一位叫Filippo Valsorda的工程师。他在业余时间给开源项目做漏洞分类(vulnerability triage),八年下来攒出一套筛选法则。最近他把这套方法公开,取名「漏洞分类的布罗卡德」(Brocards for vulnerability triage)——Brocard是法律界的行话,指那些不绝对正确、但能快速判断案子靠不靠谱的简短格言。
技术社区的反应很有意思:安全工程师转发说「终于有人写出来了」,而更多开发者第一次意识到——原来我提交的漏洞报告,在维护者眼里可能连门都摸不着。
规则一:没有威胁模型,等于没有漏洞
Alex Gaynor在2017年写过一篇《因未能陈述漏洞而驳回动议》,核心观点被Valsorda列为第一条布罗卡德:一份漏洞报告如果缺乏威胁模型,或者威胁模型自相矛盾,可以直接拒掉。
什么叫「缺乏威胁模型」?Valsorda举了个例子:有人报告Python某个API在特定情况下会抛出异常,但整篇报告没解释攻击者怎么利用这个异常造成实际伤害。异常本身不是漏洞,它只是行为。没有攻击路径,就没有安全事件。
更隐蔽的是「威胁模型比漏洞更强」。比如一份报告声称某Web服务存在内容篡改漏洞,但前提是攻击者已经是中间人(Man-in-the-Middle,中间人攻击者)。Valsorda的反驳很直接:如果攻击者能当活跃中间人,他完全可以直接发送任意内容,根本不需要「篡改」你现有的东西。这时候所谓的漏洞,不过是攻击者已有能力的子集。
另一个经典案例:通过ctypes直接操作CPython内部对象导致的内存损坏。报告者认为这是代码执行漏洞,但忽略了前提——攻击者已经在运行任意代码了。用能执行代码的能力去「证明」能执行代码,逻辑上原地打转。
Raymond Chen在2006年写过同样的事。微软的老工程师们早就明白:安全分析的第一步,是搞清楚「攻击者从哪来、能做什么、想干嘛」。没这个框架,所有技术细节都是散落的零件。
规则二:不在实际使用中的代码,没有漏洞
第二条布罗卡德更扎心:如果一段代码理论上可能出问题,但实际运行中根本走不到那条路径,它就不是漏洞。
Valsorda给了一个C代码的例子:某个内部函数接受char*指针,超过100字节会缓冲区溢出。但审计发现,这个函数只在库内部被调用,而所有调用点传入的字符串长度都受控。漏洞存在吗?技术上存在。需要修吗?优先级极低,甚至可以标记为「不接受修复」——因为引入改动本身就有风险,而收益是防范一个从未发生、也不太可能发生的场景。
这条规则在开源维护者中引发过激烈争论。2021年,Linux内核维护者Greg Kroah-Hartman公开批评某安全公司批量提交「潜在漏洞」,其中大量属于「静态分析工具报警,但无实际触发路径」。Kroah-Hartman的邮件列表原话是:「你们这是在浪费全球内核开发者的时间。」
安全研究者的反驳也有道理:今天的死代码,明天可能被重构激活。但Valsorda的布罗卡德不是绝对真理,它是分类阶段的筛子——先过滤掉明显不成立的,把有限精力留给真正需要分析的。
规则三:开发者工具里的「拒绝服务」,通常不算事
Valsorda专门花了一段讲「本地开发工具的挂起/卡死」。很多人提交漏洞报告,说某CLI工具处理特定输入时会无限循环。技术上这是拒绝服务(Denial of Service,拒绝服务攻击),但威胁模型呢?
开发者本地运行工具,卡死了按Ctrl+C就行。没有远程攻击面,没有数据泄露,没有权限提升。对比修复成本——需要重构解析逻辑、增加超时机制、处理边界情况——维护者的理性选择往往是:标记为「行为问题」而非「安全漏洞」,甚至直接关闭。
这条规则有例外。如果同样的工具被集成到CI/CD流水线,卡死可能导致构建队列堵塞,影响其他团队。这时候威胁模型变了,同一行为的定性也跟着变。Valsorda强调的不是结论,而是「先问场景」的思维习惯。
规则四:「依赖库的漏洞」需要穿透分析
开源项目经常收到这样的报告:「你们依赖的libfoo 1.2.3有CVE-2024-XXXX,请升级。」Valsorda的第四条布罗卡德是:直接转发CVE编号不等于有效的漏洞报告。
需要追问三个问题:项目是否真的调用了有问题的函数?调用时的参数是否受攻击者控制?升级版本是否引入破坏性变更?2022年,Node.js生态发生过典型案例:某流行工具收到「依赖库存在原型污染」的警告,维护者紧急升级后发现,有问题的API从未被调用,而新版本的依赖却导致构建失败,影响数千下游项目。
Valsorda把这类报告称为「CVE复读机」。安全扫描工具的普及让这类噪音爆炸式增长,维护者不得不建立自动化规则——比如要求报告者附上调用链分析,否则直接关闭。
规则五:文档与实现的偏差,优先修文档
第五条涉及一个微妙地带:代码行为和文档描述不一致,算不算漏洞?
Valsorda的倾向很明确:如果文档承诺了安全边界而代码没做到,是漏洞;如果代码行为合理但文档写错了,优先修文档。他举了加密库的例子:文档说「密钥长度必须为32字节」,但代码实际接受任意长度并自动截断。这时候修复代码可能破坏现有用户,而修复文档是零成本澄清。
这个判断有争议。2020年,OpenSSL的「文档与实现不一致」导致过生产事故:开发者按文档写代码,实际行为却不同。但Valsorda的布罗卡德针对的是「漏洞分类」场景——不是一般意义上的bug优先级,而是「这是否构成安全漏洞」的判定。安全修复往往伴随升级成本和兼容性风险,标准理应更严格。
规则六:「需要物理接触」大幅降级
硬件安全领域有个老笑话:「如果攻击者能拆开你的设备、焊接探针、读取闪存,那他也可以直接偷走设备。」Valsorda把类似逻辑写进第六条:需要物理接触或专用硬件的攻击路径,在大多数软件的威胁模型中权重极低。
具体案例:某报告声称可以通过JTAG调试接口提取密钥。如果目标设备是服务器主板、部署在托管机房,这个攻击路径确实成立。但如果目标是普通用户的笔记本电脑,攻击者能接触到JTAG接口时,已经拥有了设备所有权——这时候密钥提取是后果,不是入口。
这条规则的边界在物联网设备上变得模糊。智能门锁、工业传感器、车载系统的物理接触场景比传统软件多得多。Valsorda的备注是:布罗卡德需要结合具体上下文,没有万能公式。
规则七:竞争条件需要「可利用」证明
并发漏洞的报告往往充满「可能」「理论上」「在某些情况下」。Valsorda的第七条要求:竞争条件(Race Condition,竞态条件)类漏洞必须提供可利用的证据,或至少证明时间窗口足够宽。
现代CPU的指令级并行、操作系统的调度策略、网络延迟的抖动,让理论上的竞争条件在实践中极难命中。2019年,某主流数据库收到「连接池竞争可能导致状态错乱」的报告,维护者花了三周写测试用例,最终发现时间窗口在纳秒级别,正常负载下无法复现。报告被关闭,附带注释:「如需重新打开,请提供可复现的PoC。」
Valsorda承认这条规则有副作用:真正的竞争条件漏洞可能被遗漏。但分类阶段的资源有限,「可复现」是合理的门槛。安全研究者的回应应该是改进PoC,而不是抱怨维护者「不重视安全」。
规则八:配置错误 vs 默认安全
第八条触及开源项目的经典困境:默认配置不安全,算漏洞吗?
Valsorda的立场是:如果文档明确告知风险、提供了安全替代方案,默认选择便利性是产品设计决策,不是漏洞。但如果文档隐瞒风险、或安全方案难以启用,则构成问题。
Redis的默认无密码访问是常被引用的案例。2018年之前,Redis默认监听所有接口且无认证,导致大量实例被入侵挖矿。社区争论焦点在于:这是用户配置错误,还是产品默认不安全?最终Redis 4.0修改了默认值,但维护者的立场始终是「我们文档写了风险」——这个案例的定性至今没有共识。
Valsorda的布罗卡德不解决争议,只提供分类时的判断框架:先看文档是否诚实,再看安全方案是否可达。两者都满足,关闭报告;任一缺失,进入评估流程。
规则九:「信息泄露」需要量化影响
日志文件泄露堆栈跟踪、错误页面暴露内部路径、API返回多余的字段——这些常被标记为「信息泄露漏洞」。Valsorda的第九条要求:必须证明泄露的信息能直接帮助攻击者,或本身具有敏感性。
他区分了两类场景:泄露内部IP地址和软件版本号,通常帮助有限,攻击者可以通过其他方式获取;泄露用户会话令牌、数据库结构、或可被利用的代码路径,则构成实际风险。2021年,某云服务商的错误页面包含AWS内部服务名,被报告为「信息泄露」。安全团队评估后关闭:这些服务名对外部攻击者无价值,且AWS架构本身不依赖「隐藏服务名」作为安全边界。
这条规则的反面案例同样存在。2017年,Equifax泄露事件中,攻击者早期通过错误信息确认了Struts2的版本号,从而选择对应的漏洞利用。信息泄露的价值取决于上下文,布罗卡德的价值是强制报告者完成这个分析。
规则十:「供应链攻击」需要区分环节
最后一条针对近年激增的供应链安全报告。Valsorda发现,「供应链攻击」一词被过度使用,掩盖了完全不同的风险层级:
构建环节入侵(攻击者篡改CI/CD产出)与依赖环节入侵(攻击者上传恶意包到仓库)与分发环节入侵(攻击者劫持更新通道)——三者的检测难度、缓解措施、影响范围完全不同。混为一谈的报告,维护者无法有效响应。
2022年,Python社区处理过典型案例:某报告声称「PyPI存在供应链风险」,但全文未说明是哪个环节、假设了什么能力、可能造成什么后果。维护者的回复是:「请重新提交,明确以上三点。」
Valsorda把这条布罗卡德作为结尾,暗示供应链安全的复杂性需要更精细的分析框架,而非简单的「有/无」判断。
十布罗卡德整理完毕,但Valsorda的原文有个耐人寻味的结尾。他提到自己「花了很多业余时间做这件事」,而开源安全工作的回报机制——无论是经济回报还是职业认可——都远不及商业安全研究。2023年,GitHub的安全赏金项目平均处理时长为21天,而开源项目的非正式分类工作往往由个人在周末完成。
这套布罗卡德的本质,是用维护者的时间稀缺性反推报告质量。它不会减少漏洞总量,但可能减少无效沟通——让那3000份有效报告,更快被看见。
最后一个细节:Valsorda的博文发布于2026年4月11日,标签只有三个——oss(开源软件)、security(安全)、以及一个没解释的「pedaling」(骑行)。点进他的主页,最新动态是刚完成的一次200公里骑行。技术社区的冷幽默,大概就是这样。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.