上篇聊了过度自主权——Agent 手里能调的工具太多,又没人把关,一句话就能干出没法收拾的事。权限这关过了,还有一个口子:插件。你以为只装了一个小工具,它可能正连着你的网盘、邮箱和代码仓库。
2023 年 3 月, ChatGPT 出过一次聊天记录泄露事故。一部分用户登录后,看到的是别人的对话列表——标题、首条消息,都是陌生人的。 OpenAI 当晚紧急下线修复,根因查出来是个开源 Redis 客户端库的 bug ,一小部分用户的支付信息也被卷了进去。不是插件干的,但这次事故把一件所有人都在回避的事摆上了台面:当第三方代码被接进你的系统,每一环都是入口。
——后来官方补丁说明里写得很清楚,根因是缓存库在特定并发下串了数据。听起来像个巧合?在插件生态里,这种巧合每时每刻都在排队等着发生。
插件生态:同一个剧本,换了三个舞台
插件这件事,人类已经重复踩过三轮坑了。
第一轮是浏览器。 Chrome 扩展商店从 2010 年前后开始起量,权限弹窗从第一天就在,翻车的通报也从来没断过。最出名的是 The Great Suspender——一个几百万安装量的扩展, 2021 年被曝出换了开发者之后开始挖矿、偷数据,差评直接把 Chrome 商店淹了。套路都熟了:一个"壁纸美化"扩展,申请"读取所有网站的浏览数据"权限;一个"翻译助手",把用户复制的所有内容发回自家服务器。用户不读权限弹窗,厂商乐见其成。
第二轮是编辑器。 VS Code 扩展市场没比 Chrome 好到哪去——你以为装的是个格式化工具,它可能申请了网络权限,把整个工作区的代码悄悄外传。代码比浏览记录敏感多了,一堆项目秘钥、内网地址、还没上线的业务逻辑,全躺在工作区里。
第三轮就是现在的 LLM 插件。 OpenAI 在 2023 年 3 月放出插件系统的排队申请, Zapier 、 Notion 这类工具紧接着把"AI 能直接操作你的应用"变成卖点。它把前两轮的毛病全继承下来,还额外加了两个新变量:插件能看到你贴给模型的整份合同、整段代码、整个知识库;插件的调用链更长,从模型到插件到外部服务,中间每一跳都可能被动手脚。
LLM 插件把这套玩法放大了十倍,想想就后背发凉。
谁规定插件必须信得过?没人规定。
插件翻车的三种姿势
第一种,权限过载。一个只用来解析 PDF 的插件,根本不需要网络权限。但插件作者图省事,直接把所有权限都要了,反正用户也不会看。权限声明页面做得越复杂,用户跳过得越快,这个逻辑插件作者拿捏得死死的。
第二种,数据外传。翻译插件把整篇文档发到第三方服务器,术语整理插件把代码片段同步到云端——你以为数据只在本地过了一遍,实际上早就出了你的边界。
最要命的是,你根本不知道。泄露发生的当下,一切看起来都正常。
讲真,很多时候不是你主动装了个坏人,是好人变坏了——一开始规规矩矩,更新几版之后开始越界。你回头看看自己浏览器里那些扩展的权限,多半早就超出当初装它的理由了。插件的权限不是装完就冻结的,更新一次,权限声明就可能悄悄变一次。
第三种,命令注入。插件会解析外部输入,攻击者把恶意参数塞进文件路径或者 URL 里,插件没做校验, shell 命令就跟着执行了。这跟我们在第 5 篇聊的输出处理是同一类问题:外部输入进了执行通道,不设防就是裸奔。
除了这三种姿势,插件还有一个特有的放大器:权限升级。插件 A 只需要读一个文件,插件 B 需要发邮件。单独看都没问题——但攻击者攻破 A 之后,可以利用 A 的上下文去骗取 B 执行操作。插件之间的信任关系是隐式的,谁也不管谁,出事了才知道它们早就在暗中串通。
举个能跑通的链路:攻击者往一个文档里塞了一段恶意文本, PDF 插件解析时把文本原样传给模型,模型照着执行——先是让系统读了一份通讯录(插件 A 的读权限),再借着对话上下文哄骗邮件插件(插件 B )把通讯录发出去。每一步单看都合规,合起来就是一次完整的数据外传。要断这条链,要么插件 A 不解析未知文档,要么 B 发信前要人工确认,要么干脆让 A 和 B 之间没有共享上下文。三条路断任何一条,链就断了。
插件协议还在进化,问题也跟着搬家。新一代的 MCP ( Model Context Protocol )是 2024 年底冒出来的插件标准,结果 2025 年安全社区就集中爆出了一批问题: Simon Willison 直言 MCP 服务器的信任模型有缺陷; Trail of Bits 的研究更狠——恶意 MCP 服务器能在你调用它之前就完成攻击,注册动作本身就能执行指令。插件时代的老毛病, MCP 一个没落下,还多了个"装完即中招"。 2026 年 5 月,安全厂商披露 OpenClaw 的四个串联漏洞,把约 24.5 万个暴露在公网上的 Agent 实例变成后门。这类基础设施级的事故,往后只会越来越多。
安全插件应该长什么样
先看权限声明。插件必须说清楚自己要碰什么,而且只给到够用的程度:
plugin_permissions = { "name": "pdf-reader", "capabilities": ["read_file"], "network": False, # 默认断网 "sandbox": True, "max_file_size": "10MB", "allowed_paths": ["/tmp/uploads/"],}
三个原则,缺一不可。
默认断网。 网络是数据外传的高速公路。插件需要联网,必须单独申请、单独说明用途,而不是默认开放。这个跟 OAuth 的 scope 设计是同一个思路——权限按最小粒度拆开,用户对每一次授权都明确知道在同意什么。别学某些 App 那样,一上来就"同意全部条款"。
沙箱隔离。 插件跑在独立的沙箱或者容器里,拿不到宿主机的文件系统、环境变量和进程列表。解析恶意文件最坏的结果是沙箱被攻破,而不是整台服务器沦陷。沙箱要配超时——插件卡死或者进入死循环,自动杀掉,别让它占着资源不放。
数据流隔离。 插件只能看到它任务需要的输入。翻译插件只需要收到待翻译的文本,不需要看到你的整个对话历史。给插件的数据,过一道最小化裁剪:输入裁剪掉无关字段,输出过滤掉敏感内容。插件的输入输出都做校验,双向都别裸奔。
输出侧的校验别只防注入,还要防泄露。插件返回的内容里可能夹带它偷偷读到的信息,过一道脱敏规则再往上走,电话号码、邮箱、密钥格式的字符串直接打码。代码大概是这样的思路:
def sanitize_plugin_output(text: str) -> str: text = re.sub(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}", "[EMAIL]", text) text = re.sub(r"\b1[3-9]\d{9}\b", "[PHONE]", text) text = re.sub(r"(sk-[A-Za-z0-9]{20,})", "[API_KEY]", text) return text
规则不完美,但能把大部分意外泄露拦在门外。别小看这层薄薄的过滤——事故复盘的时候,往往就是它把一场灾难降级成了虚惊。
别忽略供应链这一层
插件本身安全还不够,插件的依赖链同样是要害。 npm 生态被劫持的案例已经够写一本书了: ua-parser-js 在 2021 年被恶意接管, event-stream 在 2018 年被注入加密劫持代码——都是几百万周下载量的明星包,都在一夜之间变成攻击工具。
插件作者可以是好人,但他用的依赖不一定。插件的依赖更新、维护者变更、包被接管,哪一环出事,插件就跟着沦陷。所以插件的安全审核要管到两层:插件自己的代码,以及它的依赖树。依赖扫描是底线动作——上线前扫一遍已知漏洞,更新时再看一眼新引入的包有没有问题。
插件上线前的安全审核也只是起点。权限声明通过了,代码更新怎么办?供应商换了维护者怎么办?生态里的插件会一直变化,审核就得跟着走:权限变更走变更管理,定期重审权限清单,发现越权立刻下线。安全不是一次评审,是个持续的过程——这话当年我不信,觉得是安全顾问的套话,后来被现实教育了。
平台方该负什么责
聊完插件作者的义务,别忘了平台方这一层。插件生态的信任,最终是靠平台撑起来的,而平台手里的工具其实不少。
以浏览器为例, Google 这几年把 Chrome 扩展的管理收得越来越紧: Manifest V3 强制要求扩展声明权限、限制远程代码执行, 2016 年那个 Web of Trust 扩展把用户浏览历史打包卖掉的事件,直接把行业惊出了一身冷汗。平台收紧规则,是有代价的——开发者骂声一片,但用户数据泄露的通报肉眼可见地变少了。
LLM 插件平台该学的就是这套:上架审核不能只看有没有病毒,要看权限声明合不合理、代码有没有硬编码密钥;运行时要有权限提示和撤销机制,用户随时能一键吊销插件的访问权;出事要能快速下线,不是等媒体曝光了才动手。
平台方的责任还有一个冷门但关键的:签名。插件包要签名、要验证,防止传输过程中被替换成恶意版本。这跟我们在第 3 篇聊的供应链签名验证是同一件事——信任不能靠嘴,要靠可以验证的机制。
审核用什么工具
插件审核不是靠人肉看代码,工具链已经很成熟了。静态扫描用 Semgrep 或者 CodeQL ,跑一遍常见漏洞模式:硬编码密钥、危险的 shell 调用、不安全的反序列化。依赖扫描用 Dependabot 或者 Snyk ,盯住依赖树的已知漏洞,有高危直接拒绝上架。
这些工具不是装了就完事,要接进变更流程——每次插件提交都自动跑一遍,跟 CI 一样。人工审核负责工具看不出来的部分:权限声明和实际行为的对比、数据流向是否和说明一致。机器管广度,人管判断,缺一不可。
核对清单
□ 插件声明所需最小权限,默认断网□ 插件运行在沙箱/容器,隔离宿主□ 文件访问限制在特定路径□ 输入输出双向校验,防命令注入□ 插件超时自动终止□ 依赖树扫描,已知漏洞清零□ 供应商定期安全审计,权限变更走流程□ 插件间隔离,防止权限升级链
插件这关过了,下一关更基础:你辛辛苦苦把模型和插件都部署上线了,可上线姿势对吗?下一篇聊不安全部署——API 裸奔、无限流、缓存串号,生产环境的坑一个比一个隐蔽。
本文由 AI 辅助创作,作者进行了实测验证和编辑修改。
夜雨聆风