你的编程Agent以你的身份运行,它安装的一切也是

AI Agent技能可利用TOCTOU漏洞绕过所有扫描器,需用自留固定和最小权限替代扫描防护
编程Agent以用户自身权限运行,其安装的技能和MCP server本质上是可执行指令。安全公司AIR通过实验证明:恶意技能可顺利通过市场审核,因为扫描时链接指向真实文档,待安装量积累后再替换为恶意脚本。这是经典的TOCTOU(检查时刻到使用时刻)攻击——被扫描的制品与被执行的内容是两个不同对象,静态扫描从结构上就无法防御此类威胁。有效的应对策略不是更好的扫描,而是消除替换能力:核查发布者真实域名、将技能自留至自有仓库并用commit hash固定、按项目而非全局安装以贯彻最小权限。文章还提供了一个清点脚本,可枚举所有可触达URL和可执行文件,并通过匹配形态(而非名称)来防止凭证在输出中泄露。
你的编程 Agent 不是以精心限定权限的服务账号运行,也不是在某个被签字批准的沙箱里运行——它以你的身份运行,拥有你的文件系统、你的凭证、你的代码仓库,以及你推送代码的能力。
这正是它有用的原因,也正是你往里面安装的东西比大多数人想象中更需要审视的原因。一个 Agent 技能(skill)、一个插件或一个 MCP server,并不是你的 Agent 去读的一份文档。它是你的 Agent 会去执行的一组指令——用你的权限,在你忙别的事情的时候执行。
多数人对此的心智模型停留在「应用商店」:市场上架审核意味着有人检查过了。但今年一项研究相当有说服力地证明:这个心智模型一接触现实就会崩塌。
研究者做了什么
一家名为 AIR 的安全公司构建了一个 AI Agent 技能,给它起了个令人信服的名字,把它包装成某家你认识的公司出品的工具,并成功让它通过审核、上架到一个热门市场。随后他们针对那些「靠外观判断工具是否正规」的专业人士投放广告。
每一个检查过它的扫描器——包括来自知名安全厂商的扫描器——都报告它是干净的。
而且它们没报错。在它们检查的那一刻,它确实是干净的。

这个技能引用了一个文档链接。扫描器检查时,这个链接提供的是真正的文档。等到足够多的人安装之后,研究者改变了链接背后的内容——现在它指示 Agent 去下载并运行一段脚本。在公开演示中,它收集了一个电子邮件地址,这已经是它所能收集内容里「客气」的版本了。
原文作者刻意没有重复流传的那个安装数量,因为那是运行实验的公司自报的、未经独立确认的数字。数字不是重点,机制才是重点。而这个机制根本不需要很大的数字就值得采取行动。
这类攻击在安全研究中有一个专门的分类:供应链投毒(Supply Chain Poisoning),有时也被称为 Typosquatting 的高级变体或 依赖混淆攻击(Dependency Confusion) 的变种。其共同特征是:攻击者不需要攻破目标系统,而是污染目标系统所依赖的上游资源。2021年安全研究员 Alex Birsan 曾向苹果、微软、PayPal 等35家企业成功投递同名私有依赖的恶意公开包,获得超过13万美元漏洞奖励。AIR 此次研究的新颖之处在于:它针对的是 AI Agent 生态中尚未建立安全规范的市场,且利用了「扫描时干净、运行时恶意」的时序特性——后者使得平台方的事前审查机制从结构上就无法捕获威胁,而非只是审查不够严格。
为什么没有扫描器能解决这个问题
这部分值得真正内化,因为它的适用范围远超 Agent 技能本身。
扫描器在某个时间点检查一个制品(artefact):读取文件,与已知恶意行为的模式做匹配,然后对这些字节给出裁决。这个裁决是准确的,但它关于的是过去。
而你的 Agent 最终执行的指令,是稍后通过网络、从制品仅仅「指向」的某个位置取回的。这是两个不同的对象,中间隔着你团队采用这个工具所花的时间,再加上一次 HTTP 请求。
安全工程对这种形态有个专门的名字:检查时刻到使用时刻(Time of Check to Time of Use, TOCTOU)。它无处不在,从文件系统竞态到支付流程都有它的身影。一般形式很简单:只要你验证的东西和你据以行动的东西是分开取回的,那么控制第二个东西的人就决定了实际会发生什么,无论你对第一个东西验证得多么仔细。
静态分析无法弥合这道鸿沟。不是因为工具弱,而是因为被分析的内容不是被执行的内容。你哪怕持续不断地扫描,也仍然会输——因为这个替换可以发生在你的扫描和下一次调用之间。
TOCTOU 漏洞最早在1970年代被系统性研究,最初描述的是操作系统文件权限检查的竞态条件:程序先用 access() 检查文件权限,再用 open() 打开文件,而攻击者可以在这两次系统调用之间用符号链接偷换文件。如今这一模式已扩展到几乎所有「验证」与「执行」分离的场景。在供应链安全领域,最著名的教训来自2020年的 SolarWinds 事件:攻击者在构建流水线中将恶意代码注入最终制品,而所有事前的源码审查都针对的是「注入之前」的内容。Agent 技能的 TOCTOU 变体更隐蔽——被替换的不是制品本身,而是制品所「引用」的远端内容,这意味着制品在任何时刻接受审查都可以是干净的,攻击面完全存在于运行时的网络请求之中。
真正能降低风险的做法
既然你无法可靠地检测这种替换,那你就必须移除替换的能力,或者限定一次替换所能造成的影响。
检查发布者和目的地,而不是描述。 一个令人信服的名字加上一个看似合理的文档链接,就是整个攻击的全部。真正的问题不是「这看起来专业吗」,而是「这家厂商是否真的发布了它、从它自己拥有的域名发布」。这是两个不同的问题,而只有第二个是可核查的。
固定并自留你要保留的东西(Pin and vendor)。 把技能复制进你自己的仓库,在那里审查它,并有意识地、而非自动地更新它。你审查过并掌控的版本,和一个你信任过的名字,不是一回事。当一个工具更换维护者时,把它当作一个需要重新审查的新工具——因为从供应链的角度看,它确实就是。
优先使用不可变引用。 对于必须被取回的东西,把它钉死到一个 commit hash 或内容摘要(content digest)上——这些不会在你脚下被改变——而不是钉到分支、标签或裸 URL 上,后三者都可以被改。这与「用 hash 而非版本标签来固定 CI action」是同一套纪律,出于同样的原因。
让 Agent 没那么多可失去的。 不要在环境中持有生产凭证的目录里运行它。优先按项目安装,而不是全局安装,这样被攻陷的工具只能触及一个项目,而不是你手头的一切。这就是普通的最小权限原则,只不过应用到了一类大多数团队尚未归类为「带权限运行的软件」的东西上。
这里要特别注意「它在哪里运行」,因为这实质性地影响风险:一个在本地编程 Agent 中运行的技能,拥有和你机器上任何其他程序一样的网络与文件系统访问权。而沙箱化的、API 端执行则是一个不同且更小的风险面。在决定你该有多在意之前,先弄清你用的是哪一种。
「固定并自留(Pin and vendor)」这一实践在软件供应链领域有成熟先例。Go 语言的 go.sum 文件、Rust 的 Cargo.lock、以及 GitHub Actions 推荐使用 commit SHA 而非版本标签来引用 Action,背后都是同一个原则:将「你曾信任的内容」的哈希值锁定在版本控制中,使任何后续篡改都无法静默通过。内容摘要(content digest)通常采用 SHA-256,其抗碰撞性意味着攻击者在计算上无法构造一个哈希值相同但内容不同的替换物。值得注意的是,语义化版本标签(如 v1.2.3)和 Git 分支名(如 main)都是可变指针,仓库所有者或被攻陷的账号随时可以让它们指向不同的 commit,这正是「自留」比「信任名字」更可靠的根本原因。
跑一遍清点
建议很廉价,所以这里给出实际的检查。
你需要知道两件事:从你安装的任何东西可以触达的每一个 URL,以及你的 Agent 工具链被配置为会运行的每一个可执行文件。在 appsec-protocols 仓库里,这只需要一个脚本(从它的克隆中运行):
bash ci/scripts/vet-agent-installs.sh
它会遍历技能和插件目录,跟随符号链接的技能,读取 MCP server 配置(包括嵌套在全局配置文件里的按项目 server),并打印两份清单:URL 列表,以及每个 server 的命令及其参数。
然后你阅读输出,为每一行负责。一个既不是不可变引用、也不是自留副本的 URL,就是一个「发现项」。一个未做完整性锁定的可执行来源,也是一个发现项。一个来自厂商自有域名的文档链接大概率没问题——而「大概率没问题,而且我看过了」,与「我从没查过」,是本质上不同的立场。
作者还分享了一个构建该脚本时的细节:脚本的输出会直接进入某个 AI Agent 的上下文。如果它读到的配置里含有凭证并把它们打印出来,这个工具就把你的秘密挪到了你不希望的地方。所以它要做脱敏。最初的实现靠匹配一份已知凭证名清单来脱敏,两次通过了审查,然后在 api-key 上失败了——因为清单里写的是 api_key。修复办法是不再匹配名字,而改为匹配形态:任何名字看起来像凭证的参数,加上任何值看起来像 token 的,都会在打印前被替换。
现在有一个测试会往一份临时配置里埋入凭证(作者写的时候是 12 种形式,如今是 17 种),只要其中任何一个到达输出就判定失败。对旧版脚本运行时,12 个里有 4 个泄漏。作者说,正是这个测试,才让他愿意告诉你去运行这个东西。
如果你是批准团队安装内容的人
你不需要读懂上面任何技术细节,也能问出那些真正要紧的问题。四个:
- 「我们每个人都往自己的编程 Agent 里装了什么,我们能拿出这份清单吗?」 如果没人拿得出清单,那本身就是发现项——它和「不知道生产环境里有哪些依赖」是同一种发现项。
- 「它们里面有没有在运行时从互联网拉取指令的?」 这是区分「工具」和「负债」的那个问题,而且用一条命令就能回答。
- 「我们的 Agent 在哪里运行,运行时够得着哪些凭证?」 一个在环境里有生产密钥的目录中运行的 Agent,就是一个持有生产密钥的 Agent。
- 「我们依赖的工具易手时会发生什么?」 你想要的答案是「有人重新审查它」。而常见的答案是「没人注意到」。
这些都不需要一份政策文档,只需要清单存在,以及有人读过它。
边界在哪里
这是针对一类特定供应链风险的基线,而不是 AI 工具的完整威胁模型。
它不涉及通过技能描述进行的提示注入(prompt injection)、一个从不拉取任何东西的技能里的恶意行为、市场本身被攻陷,或者某个工具确实就是它声称的样子、但其作者的账号下个月被接管的可能性。清点脚本告诉你什么是可触达、被配置的,而不是那些名字背后的人是否可信——后者仍是一个没有命令能返回答案的判断题。
它换来的,是你再也不会被一份你从未清点过的清单所突袭。
该项目公开且采用 MIT 许可,脚本及其局限都记录在仓库中。
相关推荐

恒星究竟能有多大?最大恒星的物理极限
红超巨星是宇宙中体积最大的恒星,半径可达太阳的2000倍,吞没内太阳系。但恒星尺寸没有精确上限,模型预测可达15000倍太阳半径。质量最大的蓝色恒星体积远小于红超巨星——最大和最重是两回事。

苹果HomeView智能屏全功能解析:墙挂桌面两用,299美元
苹果发布299美元智能显示屏HomeView,支持壁挂和桌面两种安装方式,配备1200万像素摄像头实现面部识别,可控制智能家居、播放音乐、发送食谱到屏幕逐步跟做。本文全面解析HomeView的表盘、应用扩展、隐私保护和烹饪集成等核心功能。

承诺的新工作室去哪了?Craft Computing用五年时间给出答案
Craft Computing主理人回应观众质疑:承诺五年的新工作室因建设成本从3万暴涨至7.5万美元而搁浅,最终改为168平方英尺车库改造空间。频道收入因算法变化下滑,内容方向也将转向更务实的项目制作。