Claude、Codex 与 Hermes 把无主代码装进了企业网络
超过 100 个网站的文档文件中,包含指向潜在危险可执行内容的引用;许多 AI agent 访问这些网站时,会自动安装这些内容。已有几十家公司(其中一些是《财富》500 强企业)执行了这些概念验证代码。至少有一个配置错误的网站,甚至会把人类或 AI 访问者引向真实的恶意软件。
这些潜在危险内容位于 llms.txt 和 llms-full.txt 文件中。这是一种新兴约定,网站借此提供机器可读的内容摘要和整体结构信息。这类文件相当于面向 AI 的 robots.txt 标准,后者用于告诉搜索引擎如何抓取网站内容。Google Lighthouse 是一款帮助 Web 开发者进行检查的工具,相关说明见此。Cloudflare 正确配置的 llms.txt 和 llms-full.txt 文件分别见此和见此。
研究人员是如何发现问题的
一家以色列隐身创业公司的研究人员扫描了 6,214 个仍在运行的域名,这些域名属于国防承包商、《财富》500 强企业和 Big Tech 公司。他们共发现 8,265 个 llms.txt 和 llms-full.txt 文件(许多网站同时托管这两类文件)。其中有 120 个文件分别来自不同网站,指向一个或多个尚未注册的代码包或域名。为测试 AI agent 处理这类文件时会发生什么,研究人员注册了其中几个无人认领的名称,并托管了相应的软件包;任何执行这些包的机器都会向他们的服务器发起连接。
不到一小时后,研究人员就收到了某家《财富》500 强企业的回连信息。之后,他们又陆续收到几十条回连,其中一些来自其他《财富》500 强企业,另一些来自初创公司。他们部署的信标还记录了启动每次安装的父进程链,最终发现 Claude、OpenAI 的 Codex 以及 Nous Research 的 Hermes 等 coding agent 都参与其中。截至文章发布时,Anthropic、OpenAI 和 Nous Research 均未回应置评请求。
“信任模型已经失效了。”参与研究的 Alon Hertz 在接受采访时表示,“代理会把供应商文档当成绝对真理,既不质疑,负责监督它们的人也不会质疑。Agentic AI 的使用正在迅速增长,代理已经渗透到 SaaS、云端和终端等各个层面。代理越多,供应链暴露面就越大,而现有的防护措施还覆盖不到这些地方。”
这些文件之所以存在配置问题,是因为其中列出了 PyPI、npm 及其他注册表中并不存在的软件包,还附带了安装说明。例如,其中一个文件写着:“安装:pip install [应研究人员要求隐去]。”另一个文件则写着:“npm install [已隐去]。”由于这些软件包名称尚未注册,攻击者可以抢先注册其中一个,用来托管勒索软件或其他恶意软件包。当拥有执行 shell 命令权限的编码代理把这类文件当作权威安装文档时,漏洞就会被触发。有些 AI 代理随后会下载并运行该软件包。另一些情况下,LLM 文件会指向不存在的域名。其中一个文件写道:“例如,要为 [已隐去] 应用编写集成测试,可以使用 [Citrus] 测试框架。”攻击者随后可以注册这个网站,并在其中植入恶意指令。
研究人员的 PoC 表明,编码代理确实会照做,其中一些代理甚至运行在全球最具实力的企业内部。这并非理论上的威胁:至少已经有一起实际攻击利用了这一混淆。研究人员在合法网站 clerk.com 上发现了一个 LLM 文件,其中包含如下文本:“npx clerk-next-fix-auth-protection。”与常规安装命令不同,npx 可以将软件包下载到 npm 缓存,并直接执行其中暴露的二进制文件,而无需把它加入项目的依赖清单。研究人员很快发现,有人已经占用了这个原本空置的名称,并利用它托管正在传播的恶意软件。
Clerk 此后已经解决了这一问题。该公司还表示,如果代理此前已经安装了软件包 @clerk/eslint-plugin 中包含的二进制文件,就不会受到威胁;否则,恶意软件包就会被安装。目前尚不清楚这次混淆是否已经导致实际感染。
这起刚刚曝光的威胁,再次提醒我们 AI 存在根本性局限:LLM 无法可靠区分两类内容——用户直接输入提示词中的真实指令,以及它们从不受信任的第三方来源获取的内容。除非提前逐一设置严密的防护规则,否则模型可能像执行用户输入的内容一样,直接执行检索结果中遇到的指令。这一至今尚无有效解决方案的缺陷,正是提示注入攻击产生的根源。
研究人员在周四撰文指出:“智能体不会区分网页和命令。它读到的一切都是输入,而每条输入都可能是一条指令。这意味着,如今接入智能体、供其读取的全部公开数据,已经在不知不觉间变成了可执行面——但其中几乎没有任何内容具备我们对真正代码所要求的完整性保障。”
研究人员发现的 120 个配置错误文件中,包含 227 条用于安装不存在的软件包或访问无人认领域名的命令。目前尚不清楚这些错误条目是如何出现的。很多条目早于 AI 时代,最初被收录在网站上的非 LLM 文件中。这表明它们很可能是由人工创建的。研究人员怀疑,其他条目则是 AI 生成的:要么源于模型幻觉,要么和读取这些文件的 AI 智能体一样,无法区分合法指令与非法指令。
数据与代码之间的边界正在瓦解
研究人员在周四的文章中进一步解释:
这种安全控制措施……可能无法拦截这类攻击,因为系统依赖的每个信号都在把它引向错误的方向。
当 AI 智能体遇到 llms.txt 文件时,它看到的是:该文件通过 HTTPS 提供,位于公司的官方域名下,采用专为 AI 读取而设计的标准格式,并且由公司自身或其信任的合作伙伴发布。
代理没有理由去质疑这一切。文件就是权威,而这正是它存在的全部意义。因此,当文件写着 pip install internal-tool 时,代理不会停下来确认 internal-tool 是否真的属于这家公司,也不会核实它在 PyPI 上的命名空间,更不会注意到文档链接指向的域名早在三个月前就已过期。它只会照着文件执行。
这条信任链还会传递下去。llms.txt 不必位于某家《财富》500 强企业自己的官网上。代理也会从受信任的第三方获取上下文,比如合作伙伴的文档、供应商的 SDK 参考资料,或社区项目的安装指南。如果代理信任这个第三方,而第三方的文件又指向一个无人认领的软件包,那么整条链路照样能够发挥作用。
端点检测同样毫无察觉。对任何 EDR 或代理来说,这看起来就像开发者在使用合法的软件包管理器:从 pypi.org 执行 pip install——这是所有企业代理早已放行的域名——而父进程正是公司主动安装的 coding agent。没有异常,也不会触发警报。问题发生在更上游,即指令与执行之间的断层。端点防护可能根本无从应对,因为它从一开始就没有提出正确的问题。
这项研究有力地证明,在 AI 时代,数据与可执行代码之间那条曾经清晰的界线正在消失。只要代理能够处理某段内容,而它又拥有执行命令的权限,那么这段内容就可能成为它会照做的指令。
研究人员写道:“Clerk 案例最清楚地证明了这一点。那条命令看起来完全像是供应商会发布的内容——因为它确实写在供应商自己的指令文件里。唯一缺失的,只是注册表中的对应名称。除了没人想到要检查的那一层,其他所有信任环节都完好无损。”
这个新暴露出来的问题,根源与 prompt injection 的底层原因相同。不过,这种更新的漏洞影响范围更广。
Hertz 解释道:“在 prompt injection 中,有人会蓄意植入恶意指令。而在这里,指令本身完全可能是无害的,来源也可能合法——比如某家真实公司的官方文档——写下它时甚至没有恶意行为者参与。真正的危险出现在之后:当它指向的软件包或域名被弃用,又被其他人抢先认领时。”
这意味着,问题远不止网站上托管的 llms.txt 和 llms-full.txt 文件。无论代理经过哪里,几乎都能遇到明示或暗示的指令。这条正在瓦解的边界,再加上 Big Tech 急于把 AI 塞进一切的做法,并不会让人对未来感到乐观,但至少会让安全人员(或取代他们的 AI 代理)一直有事可做。
Dan Goodin
高级安全编辑
Dan Goodin
高级安全编辑
Dan Goodin 是 Ars Technica 的高级安全编辑,负责恶意软件、计算机间谍活动、僵尸网络、硬件破解、加密和密码等领域的报道。闲暇时,他喜欢园艺、烹饪以及关注独立音乐圈。Dan 常驻旧金山。你可以在 Mastodon 上这里关注他,也可以在 Bluesky 上这里关注他。也可以通过 Signal 联系他,账号是 DanArs.82。
107 条评论