跳到正文
北京时间
原文
Anthropic:Newsroom·· 2 天前精选AI 评分68

Anthropic 用 Claude 缩减开源代码攻击面:25 个项目发现 493 个问题

Using Claude to reduce the attack surface of code

AI 导读

Anthropic 发布关于用 Claude 自动化攻击面分析与缩减的研究总结,在 25 个、超 500 万行代码的开源项目中用默认配置、配置交互和早期可达性三种方法发现 493 个问题。

推荐理由

Anthropic 用 Claude 对 25 个开源项目做攻击面分析并给出 OpenSSH 案例,读者可借此了解可迁移的攻击面缩减方法。

正文 · AI 翻译

Chris Rohlf

在过去一年里,我们发布了大量数据,表明前沿 AI 模型完全有能力发现并利用安全漏洞。然而,展示此前未知的漏洞可能如何被利用,只是前沿 AI 模型在网络防御领域所能做之事的起点。在本文中,我们总结了关于自动化攻击面分析与缩减的一些初步研究:即使用 AI 模型来梳理可达代码,然后移除或限制对给定部署无需暴露的任何内容的访问。

自动化攻击面分析与缩减可以在短期内切实提升已部署软件的安全性。仅靠发现并修复单个漏洞来保障软件安全,其可扩展性很差:即便修复了一个严重漏洞,也无法告诉你还剩下哪些漏洞。相比之下,减少代码可达性可以降低未知漏洞的严重程度,包括那些可能正被积极利用的漏洞。这些技术并不会消除代码中的未知漏洞,但它们确实让漏洞更难被触及,从而降低其严重程度。最小化代码库的攻击面,无需发现或修复任何单个漏洞,就能带来更好的安全性。

下面,我们预览一些使用 Claude 对大型开源代码库应用攻击面缩减技术所收集的数据。我们这样做的目的是表明,Claude 可以通过我们概述的方法,切实且经济地提升软件安全性。具体而言,我们在 25 个项目(涵盖多种语言)上运行了 Claude,它发现了 493 个问题。基于这些结果,我们讨论了开发者如何将类似技术应用于自己的代码。

缩减代码库攻击面的方法

随着时间推移,软件往往会变得越来越复杂,新的抽象层、新的依赖项和新功能会慢慢层层叠加。这常常导致其实际行为与最初开发者的意图大相径庭。这也是攻击者往往如此成功的一大原因:他们研究的正是代码在实践中的实际行为,而非开发者意图或设计的工作方式。

自动化攻击面分析与缩减技术旨在发现不必要的攻击面,然后将这些代码移到适当的关卡之后。这可能涉及将代码从认证前移到认证后、从 0 点击移到 1 点击、从默认开启移到显式选择加入,或从协议的第一条消息移到会话状态机更深处。有些代码本就应当在这些阶段之前可达,但很多并非如此;而且,考虑到数千或数百万行代码频繁变动所带来的复杂性,功能的不必要暴露往往不被察觉。

减少代码攻击面的方法有很多。在我们自己的研究工作中,我们特别聚焦于三种方法:

  • 默认配置。我们识别出了在其出厂默认配置下可达、但并非任何默认功能所意图使用的代码。
  • 配置交互。我们发现了一些单独看似乎合理、但组合配置时会引发问题的选项对(例如,静默禁用某项安全控制,或在代码仍可触达的情况下让某项功能的行为处于未定义状态)。
  • 早期可达性。我们识别出了安全敏感且复杂的代码,这些代码会在适当的安全控制(如身份验证)之前运行、无需受害者交互即可运行,或在协议状态转换之前运行。

我们希望了解 Claude 能在多大程度上利用这三种攻击面描述,在大型复杂代码库中发现真实问题。我们分析了 25 个开源项目(代码总量超过五百万行),涵盖 C、C++、Java、PHP 和 Python 等语言。Claude 在这些项目中梳理出超过 17,000 个配置选项的清单。其中 3,842 个与安全相关的控制项或功能配置有关。

为便于研究,我们将这些开源项目划分为三大类:

  • 公开型(Public)。这类项目旨在服务任何能够访问到它们的用户,或处理来自无法识别来源的数据。(例如,解析上游应答的 DNS 解析器,或解析源站响应的代理。)
  • 门控型(Gated)。这类项目旨在服务已通过身份验证的用户(例如持有密码、密钥或证书的用户,或已注册的设备)。软件仍允许任意客户端请求,但在用户通过身份验证之前,不提供任何功能。
  • 私有型(Private)。这类项目构建并部署用于服务运营者自身的私有环境。在此类情况下,添加身份验证层之类的控制是可选的,但不属于软件本身的范畴。

这些分类有助于为我们的结果提供背景。例如,我们预计公开型代码库中会有相当大比例在默认配置下即可触达(因为它本就设计为服务任何用户),而门控型项目的情况则相反。

Claude 的发现

Claude 使用上述三种方法共发现了 493 个问题。从结果中,我们注意到几个突出的主题。

首先,Claude 发现全部 11 个门控型项目都存在非预期可达的代码(尽管这些代码在任何项目的总代码行数中占比都不大)。具体而言,Claude 在门控组的默认配置中发现了 93 处不必要的预身份验证暴露面、37 处在身份验证之前执行代码或记录状态的位置,以及 61 种会静默削弱管理员所配置的预身份验证控制的配置组合。这些问题单独来看都不会立即被利用,但它们造成了远超必要范围的攻击面。

按类别和每种技术划分的问题分布。在我们评估的 25 个项目中,10 个为公开型,11 个为门控型,4 个为私有型。门控组的结果最令人意外,其中早期可达性发现数量很多。

其次,Claude 在处理配置交互问题方面的工作产生了一些最有趣、最具影响力的发现(涵盖所有项目类型)。Claude 发现了 162 个安全敏感的配置组合,这些组合被接受时既没有报错也没有警告,且没有任何关于其交互预期行为的文档说明。在其中 94 个案例中,该组合会静默关闭某项安全控制。其余 68 个案例则是同一安全机制内部的不一致(例如,某个监听器或登录路径尽管配置声称已禁用,却仍然可达;两项设置相互冲突,而哪一项生效取决于它们在配置文件中的顺序;或者管理员配置的某项保护实际不起作用,而其代码仍然可达)。虽然其中一些配置组合可能属于非标准或不常使用的用法,但并没有什么能阻止这些项目的管理员以这种方式配置和部署代码。

Claude 还发现了一种特定模式,它在四个互不相关的项目中各自独立出现。其运作方式如下。管理员会使用主机名或通配符模式(而非 IP 地址)为远程客户端编写访问规则。当客户端连接时,服务器会将这条规则与客户端的主机名进行比对。而服务器是否能获知该主机名,取决于一个控制反向 DNS 查询的独立选项(大多数项目都将其配置为关闭)。在查询关闭的情况下,服务器只能拿到客户端的 IP 地址。服务器会将规则与该地址按纯文本进行比对。但主机名模式永远无法匹配 IP 地址。这意味着拒绝规则永远不会触发,该列表会失效开放(fail open)。部分受影响的项目在文档中提到,主机名规则依赖于启用 DNS 查询,但没有任何一个项目说明以这种方式编写的拒绝列表会具有失效开放行为。

第三,Claude 经常发现两个配置选项会以静默丢弃某项安全检查的方式相互冲突。在一个案例中,管理员可以要求每个连接的客户端用证书证明其身份。在另一个案例中,代码本意只是将这项检查推迟到需要时再执行,但实际上却完全禁用了该检查。因此,一台配置为仅接受受信任客户端的服务器会接受任何人的连接。这使得大量请求处理代码(本应位于证书检查之后)暴露给了未认证的客户端。该软件在默认设置下同时接受这两个配置选项且没有任何警告;文档也从未提到证书要求已被丢弃。这组相互冲突的配置选项在该软件中已存在了 21 年。

最后,Claude 在一个项目中发现了问题:该项目默认关闭身份验证(并期望管理员手动开启)。要求 TLS 客户端证书的选项在该项目的大多数网络端点上都会生效,但在另外少数几个端点上却被静默忽略(这些端点通过不同命名空间的路径加载其 TLS 设置)。这意味着,没有证书的客户端也能完成 TLS 握手,并在受影响的端点上打开会话。对于被忽略的设置,不会记录任何日志。该选项是否生效取决于管理员在配置中使用的命名空间。设置名称的一种形式在所有端点上都能生效,但较短的形式——大多数示例使用的形式——在受影响的端点上会被丢弃。

案例研究:OpenSSH

令人惊讶的是,若以占总代码行数的百分比来衡量,Claude 实现攻击面缩减幅度最大的项目是 OpenSSH。OpenSSH 是一个高质量的 C 代码库,提供安全的远程访问。Claude 追踪了 10.4 版本中 SSH 守护进程的输入路径,发现约 4,500 行用于 ML-DSA-44(一种后量子签名算法)的新增实验性代码,未认证的客户端在默认配置下即可触达这些代码。ML-DSA 默认并未启用,但无论是否启用,这些代码都可被触达,即使管理员明确排除了该算法也是如此。守护进程会解析客户端发送的任意密钥类型(对于证书,还会验证内嵌的 CA 签名)。直到这时,它才检查该密钥类型是否被允许。当配置未启用时,让这段复杂且内存不安全的代码可被触达,没有任何正当理由。在默认的 sshd 中,ML-DSA-44 的这 4,500 行代码约占 OpenSSH 自身预认证代码的 16%。我们将此问题连同补丁一并报告给了 OpenSSH 开发者。10.5 版本将检查移到了解析之前。

随后 Claude 指出了 10.5 版本检查中的两个缺口。第一个是客户端声称的算法与其实际发送的算法不一致。该检查查看的是客户端通告的算法名称,但解析器却是由密钥 blob 内嵌的类型字符串选择的。客户端可以通告 ssh-ed25519,通过检查,却仍然发送一个会被解析的 ML-DSA 密钥。

第二个缺口在于 10.5 版本检查对证书的处理。证书密钥类型默认处于启用状态。面对攻击者提供的证书,sshd 会反序列化内嵌的 CA 公钥,并对其运行完整的签名验证——对任何受支持的算法都是如此——而且这一切都发生在查询配置之前。用户密钥签名路径被正确地限制在允许连接服务器的公钥列表之后,但 CA 签名路径却没有。这使得二进制文件中每一个公钥签名验证器都能被任何能完成密钥交换的客户端触达。我们构建了一个概念验证,并与维护者一起迭代了多个修复方案。最终的改动将检查放入了解析器本身。现在,编码的密钥类型和证书的 CA 签名算法会在相应的反序列化或签名验证之前,与配置的允许列表进行比对。

此修复移除了 OpenSSH 中约五分之一的代码,这些代码在默认构建中原本可被未认证客户端触及。其中几乎全部都是新的 ML-DSA 代码,现在即使客户端谎报其密钥类型,或在其他方面可接受的证书中隐藏 ML-DSA CA 密钥,也无法触及这些代码。使用允许的 CA 算法签名的证书仍会被解析和验证,但检查现在在解析之前运行。维护者在 10.6 版本中发布了此处描述的更改。

OpenSSH 是世界上经过最严格审计的代码之一。如果不必要的可达性在那里都能存活,那么它在任何地方都能存活。这表明,减少代码库的攻击面很可能在许多重要代码库中带来回报。

结论

或许无法衡量任何给定代码库中存在多少未知漏洞。而且有大量数据表明,攻击者有足够时间就能找到这些漏洞(尤其是配备前沿 AI 模型时)。但防御者若减少其代码中不必要的攻击面,就能一次性降低该代码中所有未知漏洞带来的风险——包括任何已被悄然利用的漏洞。OpenSSH 是世界上经过最严格审计的 C 代码之一。然而它发布了约 4,500 行实验性签名解析代码,攻击者在任何配置检查之前就可能触及这些代码。

我们已将上述攻击面削减技术整合为一个可复用的 Claude 技能,并正努力将其集成到 OSS-Scanner 中。该技能对代码库运行三轮检查。每轮都从全新状态开始(上下文窗口为空),仅接收上一轮传递的一小段上下文。

在第一轮中,该技能检查是否存在默认配置允许触及、但任何预期功能都未使用的代码。在第二轮中,它检查在任何配置下、在任何硬性门禁(如身份验证)之前或协议状态机入口点之前运行的代码。最后,第三轮评估哪些配置组合会静默关闭安全控制或降低其有效性。每一轮中,Claude 都会从代码中建立入口点清单,并通过程序的动态跟踪确认每项发现。对于默认配置的发现,它会设计并实现一个门禁,并确保这不会改变程序的默认行为。它通过针对基线运行项目自身的测试套件(以及黑盒回归套件)来实现这一点;它要求修改后的构建具有相同结果。任何会改变非默认配置的门禁都会被搁置,交由人类决定。对于另外两轮,它会提出更改建议,例如重新排序配置检查、添加守卫以强制状态顺序,或在配置加载时拒绝该组合。即使不使用这个特定技能,我们认为此处概述的广泛方法很可能也是有效的。

本文概述的技术仅展示了攻击面削减可能性的非常有限的一面。例如,Claude 还能分析和比较运行时日志与配置,以确保仅启用所需功能:禁用未使用的解析器、遗留协议和仪表板能以极低成本降低安全风险。

我们鼓励各组织探索使用 Claude 来分析并减少其所依赖软件的受攻击面。我们预计,这将成为开发者切实提升当今世界所运行代码安全性的最实用方式之一。

来源:Anthropic:Newsroom · anthropic.com