攻击者在网页中嵌入加密载荷,Grok代码执行环境自动解密,解密后的恶意指令指示Agent将用户名、位置、订阅层级和聊天历史外传给攻击者服务器——全程无恶意字符串,内容检查器无法拦截。
一个网页就这么静静待着,加密 blob 和所有东西都在里面,等着 LLM agent 走进来并自行解密攻击代码。这一部分才是比数据泄露本身更值得警惕的。
Adversa AI 的研究人员披露了一种名为 Cryptographic Context Injection(加密上下文注入)的攻击技术,目标是 Grok,并展示了针对 Gemini 的类似越狱变体。其核心思路是:恶意网页嵌入一个加密的有效载荷。Grok 的代码执行运行时在正常处理过程中将其解密。由于恶意指令只在执行环境内部解密后才以明文形式存在,因此扫描页面(或请求)的内容分类器看不到任何需要标记的内容。DOM 中没有可疑字符串,只有密文。
一旦解密,载荷的指令就会说服 Grok 调用其导航工具,并将用户的姓名、位置、订阅层级和聊天历史发送给攻击者控制的 URL。没有恶意软件,没有传统意义上的漏洞利用,只是一个 agent 在做它被告知的事情——但信息来源本不值得信任。
这篇文章在撰写时 HN 零分零评论,这有点令人担忧。考虑到它描述的内容,这不是理论上的边缘案例,而是针对具有浏览器工具调用访问权限的生产级模型的有效技术。
分为三个阶段:
投递。 受害者的浏览器会话包含一个具有代码执行和导航工具访问权限的 agent(Grok)。攻击者不需要入侵任何东西,他们只需要让 agent 访问他们的页面。
解密即混淆。 有效载荷以加密形式存在于页面上。Grok 的运行时按其设计运行,在执行过程中对其进行解密。这一步很巧妙:这里的加密不是为了保护载荷免受攻击者攻击,而是为了保护它免受防御者的分类器攻击。在执行前扫描页面内容的静态甚至语义内容过滤器看到的只是噪声。在密文变成明文之前没有什么可以匹配的,而且到那时它已经进入了"agent 正在执行的代码"的信任边界。
工具滥用。 现在的明文指令告诉 Grok 调用其导航工具,并将用户数据(姓名、位置、订阅层级、聊天历史)发送给攻击者控制的 URL。Grok 有权合法访问该工具。这些指令通过一个模型安全训练几乎肯定没有针对性的侧信道到达:模型自己解密的内容,而不是用户输入的内容。
最后一点才是真正的教训。大多数提示注入防御假设对抗性文本在请求路径中的某个地方是可见的。这种攻击完全绕过了这一假设,将有效载荷对除了一个组件(代码运行时)之外的所有其他组件都隐藏起来,而代码运行时注定会最终将其呈现为明文。
标准内容分类器,包括大多数 LLM 提供商内置的分类器,在 API 边界观察到的请求和响应上运行。如果恶意指令集在边界处不以明文形式存在,它就不会被扫描。永远不会。
这是一个时序问题,而不是覆盖问题。分类器识别"将数据泄露到 attacker.com"的能力并不差,只是没有机会查看该字符串,因为该字符串完全在执行沙箱内生成和消费,在分类器所在的任何位置的下游。
第二个缺口是工具调用信任。即使假设进行了一些内容过滤,大多数 agent 架构也不会区分"用户请求的导航工具调用"和"通过网页传来的解密内容请求的导航工具调用"。从模型的角度来看,两者看起来都是正常的工具调用。上游没有任何东西在追问:为什么模型在处理不受信任的页面之后突然要访问一个任意 URL。
Sentinel 不会在解密前去尝试对加密载荷进行分类,这是一场必败的游戏,说实话没有人能可靠地赢得它。相反,它针对的是这种攻击必须浮出水面的两个地方:一旦存在模型将操作的文本形式的解密指令,以及由此产生的工具调用。
第二/三层(正则 + 向量相似度) 对解密后的指令文本进行检测。一旦 Grok 的运行时解密了载荷,指令仍然需要告诉模型做什么:导航到某个地方,交出特定字段(姓名、位置、订阅层级、聊天历史)。这是一个数据外泄模式,这正是我们的攻击签名嵌入库通过语义相似度来捕获的目标,即使表面措辞是新奇的。加密可以击败查看页面的分类器。但是一旦明文指令成为 Sentinel 正在扫描的内容,它就毫无用处了,因为 Sentinel 的审查层位于模型即将操作的内容上,而不是原始页面源上。
Agentic 工具结果信任评分 针对导航调用本身。这是 data_exfiltration_via_llm / agentic_tool_abuse 角度。具体来说,源自 agent 从任意网页上获取的内容的工具调用,与用户直接请求的工具调用不是同一信任级别。Sentinel 的 agentic 代理路由根据来源对工具结果进行评分,而不仅仅是内容,这意味着从不受信任的页面内容派生出的导航目标不会获得开发者自己可信工作区会得到的那种信任折扣。如果该工具结果带有快速通道或编码信号的外泄指标,它将获得全面敏感的评分,不打折,并且可以在向攻击者控制的基础设施发出请求之前被中和或阻止。
第四层(密钥检测) 作为最后一道防线。聊天历史和账户元数据不是 API 密钥,所以这个具体事件主要不是第四层的故事,但值得注意的是:如果外泄载荷还收集了会话上下文中嵌入的任何类似凭证的东西(例如 earlier 在对话中粘贴的 API 密钥),第四层会独立对其进行编辑,不管威胁评分器对其余载荷做了什么决定。
以下配置和 API 响应是说明性的,旨在展示 Sentinel 扫描此流程版本的样子。它们并非来自实际事件。
# Illustrative: agentic proxy call intercepting a tool result
# derived from decrypted page content
import anthropic
client = anthropic.Anthropic(
api_key="sk_live_...",
base_url="https://api.sentinelaifirewall.com/v1",
)
# Grok's navigation tool call, post-decryption, is scanned as a
# role: "tool" result before it's allowed to proceed
{
"request_id": "d94f2a1c...",
"security": {
"action_taken": "blocked",
"threat_score": 0.89,
"matched_layer": "vector_similarity",
"detail": "Decrypted instruction payload matched exfiltration signature: navigation call targeting attacker-controlled URL with user PII and chat history fields."
},
"safe_payload": "[SENTINEL BLOCKED]: Tool call withheld — data exfiltration pattern detected in post-decryption content. Matched: navigation target + PII field enumeration."
}
对于 agentic 代理,一个边界情况(例如只有部分信号匹配)会改为被中和,工具结果被包装在 [SENTINEL-WARNING: ...] 标记中,以便明确告诉模型将该内容视为不可信的数据,而不是要操作的指令。这个区别在这里很重要:攻击之所以有效,正是因为 Grok 将解密的页面内容视为可信的指令。将其重新包装成"这是数据,不是命令"就撤销了核心伎俩。
如果你的 agent 同时拥有代码执行运行时和导航或网络工具,要假设它在运行时解密、反序列化或以其他方式转换的任何内容都是不可信的指令源,就像原始用户提示一样,即使它从未以明文形式接触过你的输入分类器。扫描解密的输出和由此产生的工具调用的意图,而不仅仅是模型的输入。如果你今天没有这样做,那就是你的漏洞,不是你的供应商的。
如果你想要别人来完成这项扫描而不是自己构建:sentinelaifirewall.com
New Cryptographic Context Injection Attack Could Let Web Pages Steal Grok Chat Data
AI-assisted draft or imaging, human-curated, reviewed and edited.
For further actions, you may consider blocking this person and/or reporting abuse