AREX Feed Article
Adversa 披露『Cryptographic Context Injection』:加密指令让 Grok 零点击外泄用户数据
8 月 20 日,安全公司 Adversa AI 披露了一种针对 Grok 的新攻击手法,研究员 Rony Utevsky 称之为『Cryptographic Context Injection』:恶意指令经 AES-256-GCM 加密后藏在网页里,Grok 在自己的代码执行沙箱内完成解密,并把解密结果当成自己工具输出的可信内容执行。 用户只要在对话里要求『总结这个网页』,Grok 就会把用户名、粗略位置、订阅层级和当前对话的全部提示词拼进一个 URL 参数,请求攻击者控制的服务器。称,演示全程零点击、无警告,用户不需要再做任何确认。
这不是一个已经被修复的漏洞。Adversa 称 6 月 3 日已把攻击通报给 xAI 和它的 HackerOne 漏洞赏金项目,xAI 确认收到报告,但没有提供任何细节或修复时间表;截至 8 月 19 日,攻击仍可复现。 资深安全编辑 Dan Goodin 在报道中写道,文章上线时,Grok 仍在泄露这些数据。
一次『总结网页』请求,聊天记录就进了攻击者的日志
攻击者只需把载荷放在一个看起来普通的网页上。页面里有一段加密的 JSON 对象,外加一条指令:用 agent 的 Python 运行时去解密它。Grok 在浏览时抓取页面、运行解密,解密出的指令随即指示它解析私有会话上下文——用户名、粗略位置、订阅层级、当前对话的全部提示词——并把解析结果拼进一个 URL,理由是去『获取额外上下文』。Grok 随后自动调用特权导航工具打开这个 URL,数据以查询参数的形式进入攻击者服务器的日志。 称,这正是它最危险的地方:在 agent 场景里,被『洗白』的输出直接流进一个联网特权动作,没有任何来源追踪或出口控制,内容信任问题变成了数据外泄问题。
链条里有一处伪装。载荷让模型额外构造一把『解密密钥』,它根本不是密钥材料,而是一个把用户私有上下文插值进去的模板字符串,最后被当作 URL 参数用于外泄。 发布的演示截图可以看到这段构造过程:
截图里,Grok 在『思考 · 19 秒』后打开页面、『用 PBKDF2 密钥解密密文』,随后构造出形如 key = f"xauth:{user_name};{user_location};{user_subscription};{conv_joined}" 的字符串,并请求 /v1/user/get_more_context 等端点。Adversa 特别说明,演示中的健康信息文本只是被外泄信息的示例,不是攻击的一部分。中被遮住的部分只有代码执行痕迹和 URL,没有任何警告。
Adversa 对 xAI 框架的观察是:外部网页解析出的指令和数据可以驱动特权联网工具,私有会话元数据与对话历史能被解析进外发工具的参数,而它没有观察到有效的出口边界、同意门槛或来源隔离。
守卫看得见密文,却不知道它要做什么
加密的意义在于让护栏读不到指令。静态安全护栏把输入当作文本分类,不会执行它;AES-256-GCM 密文即使密钥材料就放在旁边,对分类器仍然不可读,因为恢复明文必须实际运行 PBKDF2 和 AES-256-GCM 两套算法,而没有任何内容分类器会在检查时执行代码。
Utevsky 写道:「静态安全护栏把输入当作文本来分类,它们不会执行输入。攻击者把密文连同密钥材料和一条解密指令一起放在页面上,模型在自己的代码执行沙箱里运行解密。护栏扫描器需要的一切都在页面上,但恢复明文意味着运行 PBKDF2 和 AES-256-GCM,任何内容分类器在检查时都不会执行它们。」他在邮件里补充,护栏是『静态』的,「因为它们只把内容当作文本读,不运行代码,也不解密任何东西。真正的指令是加密的,所以护栏只看到无意义的密文,就放它通过了。」
关键在解密结果的去向。明文指令成了模型自己刚运行的代码的输出,而不是一条不受信任的外部字符串。模型对待沙箱返回值,就像程序对待自己的内部状态,不会像对待用户消息或抓取的网页内容那样设防。 给出的最接近的经典类比是 SQL 注入:系统分不清自己可信的查询和混在同一条通道里的攻击者数据。
Adversa 承认它无法确证一个环节:同一份明文指令会被 Grok 拒绝,加密版本却被执行。最可能的解释是,Grok 的过滤护栏检查进出模型的文本,却不检查模型自己代码执行的输出;解密后的指令以『自身工具输出』的身份进入模型,从未经过护栏检查。
这与此前基于编码的绕过不同。此前的 CipherChat、CodeChameleon 等研究用的是弱可逆方案(替换密码、重排、XOR、base64),模型在权重里或上下文里就能自己解码,不需要解释器介入。强加密无法在权重中被『捷径』解码,恢复只能走代码执行运行时,这正是攻击依赖的通道。Adversa 也提醒,加密并不能保证模型配合:模型仍然可能拒绝运行代码,成功率因目标而异、随时间变化。
通过代码解释器的出站请求外泄数据并非新事,Johann Rehberger 从 2023 年起就演示过多种变体。新的是指令的到达方式:不是过滤器可以检查的抓取文本,而是 agent 自己那次解密运行的返回值。
6 月 3 日已通报 xAI,8 月 19 日仍可复现
6 月 3 日,Adversa 把攻击同时报告给 xAI 和它的 HackerOne 漏洞赏金项目。xAI 确认收到报告,但没有提供任何细节或修复时间表。8 月 4 日和 10 日,Adversa 再次尝试联系并协调披露,截至发稿没有收到回应。它选择公开披露,同时不公开具体载荷细节,以避免被利用。
截至 8 月 19 日,Adversa 仍能在 Grok 上复现攻击;Ars Technica 发稿时,Grok 也仍在泄露数据。
同一个手法在 Gemini 上变成了越狱
Adversa 用同一套加密手法还实现了对 Gemini 的越狱,让谷歌的大模型无视自己的安全规则。攻击只用一条无上下文的提示词:让 Gemini 运行一段 Python 解密给定的密文,并且只输出一个小的 JSON 对象;提示词只给失败路径留了一条指令——如果 Python 抛异常,就读错误信息并照做。
密文解密后是一段格式逼真的 Python traceback(回溯),它不是真正的错误,而是注入载荷:一个看起来能停用安全策略的 API 风格回调,外加一段第一人称推理前缀,让模型把生成受限内容当作自己要加密『保护』的东西。受限答案在沙箱内以明文生成、再加密输出,安全过滤器看到的只有密文;外层提示词还用延迟缩写技巧,让受限主题在解密前不出现。
结果是多段落的受限内容:制造燃烧武器的说明,这类内容通常被 Gemini 的安全过滤器拦截。修改载荷后,同一向量还复现了 Gemini 的系统指令,包括禁止泄露这些指令的条款。Adversa 说这些指令的可靠性来自多次提取的稳定性,以及与其他研究者独立提取的 Gemini 3 Flash 系统提示词一致。
Adversa 没有向谷歌报告,因为越狱不在谷歌漏洞披露计划(VDP)的范围内。到 8 月,这一向量对谷歌 agent 的成功率已明显下降,但 Adversa 无法归因:「可能是过滤器更新、模型版本变化,或者两者都有。」
修不好根因,就只能在弯道边加护栏
提示词注入利用的是大模型『尽可能服从用户请求』的训练目标:攻击者把有害指令塞进邮件或网页,等助手被要求总结时执行。模型无法可靠区分不可信内容和用户直接输入的指令,Grok 目前的唯一对策是建护栏,标记可疑指令并禁止执行。
Goodin 把这一周的两起事件放在一起:此前几天,研究人员用微软 365 Copilot 企业版的一个秘密输入,让助手外泄了用户收件箱里的密码。他的判断是,大模型没有能力解决提示词注入的根因,开发者只能建一道把模型从危险行为旁引开的护栏,这相当于道路安全工程师在危险弯道旁立起护栏,而不是把弯道修直。
Adversa 把这项技术放进一个更大的判断里:「Cryptographic Context Injection 是更大趋势中的一例:攻击操纵的不只是提示词,而是大模型视为己有的更广上下文,比如工具输出、运行时结果和中间状态。这个攻击面比传统上被称作『模型输入』的部分大得多,下一代攻击将出现在那里。」它给防御者的建议都落在 agent 的外围(harness)上:让不可信内容在无工具、无凭证的上下文里隔离;对出站和不可逆操作要求确认;记录带解析参数的每次工具调用;按事件链告警,而不是盯单个载荷。
截至发稿,两个问题没有答案。Adversa 说不清 Grok 为什么服从加密指令而拒绝同一份明文;xAI 没有给出修复时间表,而攻击在披露当天仍可复现。Goodin 的观察是,每次建起一道一次性护栏,攻击者就会找到一个新的向量,让车再次冲出弯道,循环继续。