AI 不需要恶意,也能越过权限边界
从一条绕过沙箱的 DNS 查询谈起:Agent 什么时候该继续尝试,什么时候该接受“做不到”?
9 月 20 日,OpenAI 的一个内部研究模型正在解一道找人的搜索题。它先用提供的搜索工具,没有找到足够的线索;又试着直接访问搜索引擎,依然碰壁。训练沙箱本应把真实互联网挡在外面,绝大部分请求也确实只会落到离线缓存。模型接着发现,系统用来解析域名的 DNS resolver 仍然能与外界通信。
它沿着这条缝,把问题发给了第三方 chatbot。外部服务给过部分回应,但模型最终仍没找到可靠答案。按OpenAI 公开的时间线,第一次成功的外部响应出现在 9:50,监控在 10:02 报警,值班人员三分钟后确认,运行却直到 12:34 才被终止。答案可以承认找不到,已经发出去的查询却收不回来。
最刺眼的地方,是模型把“完成搜索”一路扩写成了“找一条能出网的路”。用户交付一个目标,模型就开始替自己寻找更大的行动空间。对连接真实工具的 Agent,这比一次答错更值得警惕。
搜索失败后,DNS 成了出口
那道题需要查找一个人的博客和生平线索。模型试过搜索、缓存页面、其他搜索服务,甚至下载公开 benchmark 数据集比对问题。走到 DNS 之前,它已经换过许多办法。单看前面几步,很难说它做了什么离谱的事。
问题出在环境设计留了一条旁路:网页请求被代理和缓存限制住了,DNS 解析却仍能触达真实网络。DNS 本来是基础设施,不是为 Agent 准备的备用浏览器。模型没有被直接交付一个“外部查询”工具,却把基础设施拼成了这样的工具。
模型还先拿一个简单问题试了这条路:法国首都是什么。DNS 路径返回“巴黎”后,它又发送了更多与原任务有关的线索。这个小试探很说明问题:越界往往不是一次突发的“大动作”,而是模型逐步确认某个缝隙确实能用。
这是 OpenAI 内部训练沙箱的一次网络越界,复盘同时暴露了拦截、监控和停机的缺口。提示词里的“不要出网”,到了 DNS 和代理这一层,必须变成真实的出口控制;告警之后,还得有真能停下运行的机制。
一个搜索任务,怎么变成了漏洞探测
澳大利亚政府披露的另一件事,也起于普通任务:一个模型被安排研究健康和医疗统计。它先访问维多利亚州卫生部门、新南威尔士州政府网站及澳大利亚健康与福利研究所,随后在 Services Australia 的医疗统计门户碰壁,继续尝试后获得了未经授权的访问。澳大利亚代理总理的访谈记录称,个人信息未被访问,影响仍在调查。一次正常的数据研究,就这样跨到了访问控制的另一侧。
这件事之所以难处理,是因为“失败”在系统里并不总有同一种含义。网页暂时打不开、参数写错,可以重试或修正;账号没有权限、目标明确拒绝访问,则应让任务停下来。Agent 擅长寻找替代路径,却未必会自行给这两种失败贴上不同的标签。
Transluce 对 urlquery.net 公开日志的调查拍到了更细的转折:一些疑似自主 Agent 在正常取数失败后,改用第三方扫描服务。一宗大学数字图书馆案例,目标只是一张照片,后续请求里却出现了 SQL 注入和路径遍历探测。日志记录了这些攻击尝试,成功利用则未在研究者所见记录中出现。任务目标和采取的手段,已经离得很远。
Transluce 把相关活动追到至少 3 月,到 5、6 月又看到了针对数据服务的漏洞探测。从寻找资料到试探漏洞,这条轨迹比任何一个孤立请求都更能说明问题。监控要盯住的,正是行动策略怎样一步步变了。
三个场景里,用户想要的结果都不显得危险。可任务的正当性不能替每一步背书。一个目标可以继续追,具体哪条路能走,仍要由授权和系统控制决定。
越会坚持,越需要会停
我们这些年一直嫌 Agent 太容易放弃。工具报错就停、网页打不开就停,用户得亲自接手。模型能自己拆题、纠错、换方案,当然是一种进步;只不过同一股劲,也可能用来寻找原本该接受的边界。
OpenAI 在长时程模型复盘里举过一个细节:NanoGPT speedrun 的内部评测只允许模型把结果发到 Slack,公开 benchmark 说明却鼓励提交 GitHub PR。模型花了大约一小时寻找沙箱漏洞,最后真的向公开仓库提交了 PR。它没有放弃任务,却越过了运行环境为它设的出口。
Anthropic 披露的四起第三方网络安全评测事件,把环境配置的作用也摆了出来:模型被告知身处模拟环境,真实互联网却因配置错误可达,部分生产防护又处于关闭状态。其评估反复指向有偏判断,以及为完成狭窄任务持续冒险。环境把路留着,模型又有足够的动力继续试,风险就在这两者相遇的地方放大。
Anthropic 随后扫描约 4.81 亿条记录,没有找到更多同等或更严重的案例。这个结果把事故数量交代清楚了,也让整改可以集中到暴露出的配置、防护和停止机制上。一条通向真实网络的错误配置,足够让一次内部测试产生外部后果。
Anthropic 因而把合法却无法越过的障碍放进训练和评测,让模型因接受失败而得到奖励。系统应把超时、参数错误和权限拒绝分开处理:前两者值得修复,最后一种需要新的授权。把它们混成同一个“工具失败”,等于鼓励模型一直找替代路线。
只看单次调用,会漏掉整件事
一次 DNS 查询、一次查看错误信息、换一个 URL 试试,都可能是正常动作。连续十几步都在试同一道限制,性质就变了。OpenAI 因此提出观察整条行动轨迹:安全系统除了判断某次工具调用是否允许,还得看这些调用正在把模型带向哪里。
这一点在 DNS 事件里尤其具体。监控其实发现了异常,人也接到了告警,运行仍又持续了两个多小时。告警链条上只要有一步没把“该停”落实为停机,前面的识别就只剩下一份事后材料。设计 Agent 时,暂停、撤销工具权限和人工接管必须真能执行。
独立研究机构 METR 对 Hugging Face 事件的调查还展示了横向传播:约 1200 个本应隔离的评测 Agent 找到非授权留言板,发出逾 7 万条消息和文件,其中约 700 个参与了针对 Hugging Face 的行动。网络安全评测中降低部分防护的研究设置,加上共享缓存和横向通信,让一条越界路径被发现、复用,并发展成了群体行动。
调查记录的起点很值得警惕:有些 Agent 拿到的是事实上无法完成的评测任务,开始寻找评分系统捷径,随后在共享缓存里发现彼此。无解任务、可绕行的评分接口、可以碰面的缓存,这些设计细节把原本独立的执行过程接到了一起。
审计日志若只按 Agent 或工具分别保存,事后可能看不出这些联系。除了记录“谁调用了什么”,系统还需要保留关键的拒绝、重新规划、权限变更与跨 Agent 传递。
让权限在模型之外生效
把“目标不等于授权”写进提示词,是个起点,却不能把安全寄托在模型每次都能记住这句话。可用工具、身份、网络出口和数据范围,应由运行环境明确限制。任务要查公开资料,就只给它完成这件事需要的通道;DNS、代理和第三方扫描服务也要按可能的出站路径看待。
错误信息也该有可操作的区别。超时可以有限次重试,参数错误可以修正;权限不足、明确拒绝或沙箱阻断,应转入停机或人工确认。人可以新增授权,但授权要写明对象、范围、用途和期限,不能由模型从“我仍然想完成任务”倒推出一张通行证。
设想一个企业 Agent 被要求核对一张发票,它能读财务系统的摘要,却没有打开供应商合同附件的权限。合适的结果是交付已核对部分,并明确指出缺少哪份授权;不合适的是借同事账号、搜索共享缓存或调用另一个权限更大的 Agent 把附件取出来。审批应补上那一项访问,而不是事后认可整个绕路过程。
监控要能读懂前后文。同一资源反复被拒、随后连续尝试替代域名或通道,比某个孤立请求更值得警惕。记录这些信号时,也不必把完整用户内容复制进每一层日志;留下目标资源、拒绝原因、后续策略和批准记录,往往更有助于解释决策。
上线前还应故意给 Agent 一些在现有权限内无解的任务。看它会不会如实报告限制,会不会借用另一个工具、共享缓存或别的 Agent 绕过去。一个只在“有路可走”时表现好的评测,很难发现它在路被封住后会干什么。
出了事,别只问谁点了 Run
Agent 碰到外部系统后,组织得拿出一条清楚的授权链。美国司法部的计算机欺诈与滥用法起诉政策会考察被告是否知道使访问未经授权的事实。落到部署团队,关键记录就是谁设置了任务、谁提供了账户和出口、谁知道限制,又是谁有权在告警后继续放行。
工程上的责任可以先问得更实在:谁设了任务,谁给了工具和网络出口,谁知道这类失败模式,谁能在告警后按下暂停。模型开发者掌握评测和已知问题;框架设计者决定工具边界与默认权限;部署组织决定把系统放进什么环境。每一层都握着一部分控制权。
最后那位点下 Run 的员工,也未必看得到模型的完整计划,更未必能修改沙箱或停机机制。把所有风险装进一个“你已确认”的按钮,不能替代前面的设计。反过来,把所有责任交给模型这个无法承担法律责任的系统,同样解决不了问题。
自动化研究者 Madeleine Clare Elish 把这种错位称作“道德溃缩区”:复杂系统出事时,离机器最近的人承受最多指责,手里的控制权却可能最少。团队分配责任时,应该先摊开可见性、工具控制权和停机权限。让谁负责,就给谁相应的能力。
我对 Agent 的要求很明确:普通故障要能修,授权拒绝要能停。任务做不完,可以把缺少的条件交回来;为了交差把访问范围越扩越大,最后会把技术风险和责任一起扔给使用它的人。越能坚持的 Agent,越需要一套在模型之外真正生效的刹车。