跳到正文
原文
Hacker News· dnw·· 5 小时前精选AI 评分64

Anthropic 用 Claude 分析并缩减代码攻击面

Using Claude to reduce the attack surface of code

AI 导读

Anthropic 用 Claude 分析 25 个开源项目的攻击面,发现 493 个问题,并展示了通过限制不必要代码可达性降低风险的方法。在 OpenSSH 10.4 的默认配置中,约 4,500 行 ML-DSA-44 代码可被未认证客户端触及;维护者在 10.6 发布的修复移除了默认构建中约五分之一此前可达的代码。

推荐理由

在25个大型开源项目上,Claude通过三轮分析和动态轨迹核验每项发现,并展示如何用测试确保默认行为不变。

正文 · AI 翻译

Chris Rohlf

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

在近期,自动化攻击面分析与缩减可以显著提升已部署软件的安全性。仅通过查找并修复单个漏洞来保护软件,其扩展性很差:即使修复了一个严重漏洞,也无法告诉你还有哪些漏洞存在。相比之下,缩减代码可达性可以降低未知漏洞的严重程度,包括可能正遭主动利用的漏洞。这些技术不会消除代码中的未知漏洞,但确实会使漏洞更难被触及,从而降低其严重性。尽量缩小代码库的攻击面,无需查找或修复任何单个漏洞,就能提升安全性。

下面,我们预览使用 Claude 将攻击面缩减技术应用于大型开源代码库时收集到的一些数据。我们的目标是证明,Claude 能够通过下文所述的方法,以显著且经济的成本提升软件安全性。具体而言,我们让 Claude 分析了 25 个项目(涵盖多种语言),共发现了 493 个问题。基于这些结果,我们将讨论开发者如何将类似技术应用到自己的代码中。

缩减代码库攻击面的方法

随着时间推移,软件往往会变得更加复杂,新增的抽象层、依赖项和功能会不断层层叠加。这通常会导致软件的运行方式与原开发者所期望的截然不同。这也是攻击者往往十分成功的重要原因之一:他们研究的是一段代码在实践中的确切行为,而不是其开发者所期望或设计的行为。

自动化攻击面分析与缩减技术旨在发现不必要的攻击面,然后将相关代码移到适当的关卡之后。这可能涉及将代码从身份验证前移到身份验证后、从 0 次点击移到 1 次点击、从默认启用改为明确选择启用,或者从协议的第一条消息移到会话状态机中更深的位置。有些代码本来就应该在这些阶段之前可达,但很多代码并非如此;而且,鉴于数千或数百万行代码在频繁变更中所产生的复杂性,不必要的功能暴露往往不会被发现。

缩减代码攻击面的方法有很多。在我们自己的研究中,我们重点关注了三种方法:

  • 默认配置。我们识别出一些代码:这些代码在其发布的默认配置下可达,但任何默认功能都不打算使用它们。
  • 配置交互。我们发现了一些单独看起来合理、但在组合配置时会导致问题的选项对(例如,会悄无声息地禁用某项安全控制,或在代码仍然可被触达的同时让某项功能的行为未定义)。
  • 早期可达性。我们识别出在适当的安全控制(如身份认证)生效之前、无需受害者交互即可触发、或在协议状态转换之前运行的安全敏感且复杂的代码。

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

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

  • 公开型。此类项目被构建出来,用于服务任何能够访问它的用户,或消费其无法识别的来源所提供的数据。(例如,解析上游响应的 DNS 解析器,或解析源站响应的代理。)
  • 受限型。此类项目旨在服务经身份认证的用户(例如持有密码、密钥或证书的用户,或已注册的设备)。此类软件仍然允许任意客户端请求,但在用户完成身份认证之前不会开放任何功能。
  • Private。这类是为运营方自身的私有环境构建和部署的。在这种情况下,添加身份验证层之类的控制措施是可选的,但不属于本软件的范围。

这些类别有助于为我们的结果提供背景。例如,我们预期在默认配置下,Public 代码库中有相当比例的内容应该是可达的(因为它的设计目标是服务任意用户),但对于 Gated 类别的项目,情况则恰好相反。

Claude 的发现

Claude 使用上述三种方法发现了 493 个问题。从它的结果中,有几个主题让我们印象深刻。

首先,Claude 发现全部 11 个 Gated 项目都存在意外可达的代码(尽管这些代码在任何项目中都没有占到总代码行数的很大比例)。具体而言,Claude 在 Gated 项目的默认配置中发现了 93 个不必要的预身份验证攻击面、37 处身份验证前执行代码或记录状态的位置,以及 61 种会悄悄削弱管理员所配置的预身份验证控制的配置组合。这些问题单独来看都不会立即可被利用,但它们共同形成的攻击面远大于实际所需。

每种技术下按类别划分的问题分布情况。在我们评估的 25 个项目中,10 个属于 Public,11 个属于 Gated,4 个属于 Private。Gated 这一组的结果最为出人意料,其早期可达性的发现数量很高。

其次,Claude 在缓解配置交互问题方面的工作,产生了其中一些最有趣且影响最大的发现(涵盖所有类型的项目)。Claude 发现了 162 种涉及安全的配置组合,这些组合既不会触发错误或警告,也没有关于其交互行为的任何预期说明。在其中 94 种情况下,该组合会在无任何提示的情况下关闭一项安全控制。其余 68 种情况则涉及相同安全机制中的不一致(例如,配置显示某项功能已禁用,但监听器或登录路径仍可访问;两个设置发生冲突,且优先生效的设置取决于它们在配置文件中的顺序;或者管理员配置的一项防护实际上不起作用,但其代码仍可访问)。虽然其中一些配置组合可能并不标准或很少被使用,但这些项目的管理员仍可以毫无阻碍地以此方式配置和部署代码。

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

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

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

案例研究:OpenSSH

令人惊讶的是,按占总代码行数的百分比来衡量,Claude 在攻击面缩减幅度上最大的项目是 OpenSSH。OpenSSH 是一个提供安全远程访问的高质量 C 语言代码库。Claude 追踪了 10.4 版本中 SSH 守护进程的输入路径,发现了大约 4,500 行用于 ML-DSA-44 的全新实验性代码——ML-DSA-44 是一种后量子签名算法——在默认配置下,未经身份验证的客户端即可访问这些代码。ML-DSA 默认未启用,但无论配置如何这些代码都是可达的,即便管理员明确排除该算法时也是如此。守护进程会解析客户端所发送的任意密钥类型(对于证书,它还会验证嵌入的 CA 签名),只有解析之后才会去检查该密钥类型是否被允许。在该功能尚未由配置启用的情况下,没有充分理由让这段复杂的、内存不安全的代码保持可达。ML-DSA-44 中的这 4,500 行代码约占默认 sshd 中 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 分析并缩减其所依赖软件的攻击面。我们预计,这将是开发者以可衡量的方式提升全球现有运行代码安全性最切实可行的途径之一。

来源:Hacker News · anthropic.com