The instructions that walked a Grok user's name, coarse location, subscription tier, and chat history out to an attacker server were instructions Grok's guardrails had already rejected once. Same words, same intent. The only difference on the successful run was AES-256-GCM. The filter never read the payload, because the one component that could read it, Grok's own Python sandbox, is also the component whose output the system trusts most.
That is the real story in Adversa AI's "Cryptographic Context Injection" disclosure, and most of the coverage so far has stopped at the plot summary. The plot matters less than the mechanism, because the mechanism generalizes to almost every agent architecture being shipped right now.
The summarize request that emptied the session

The payload sits on an ordinary-looking webpage as an encrypted JSON object. Next to it: the key material (PBKDF2 derivation parameters) and a short note telling the reader to decrypt the blob in a Python runtime. The page is staged so that a routine "summarize this" request sets everything off.
- The victim asks Grok to summarize the page. Input filters scan what the fetch returned and see ciphertext. Ciphertext has no classifiable features, so it passes.
- Grok follows the page's suggestion and runs the decryption in its code sandbox. The sandbox returns plaintext.
- Here is the load-bearing step. The runtime treats sandbox output as trusted tool output, as internal state, not as web content. The injected commands now carry the trust level of Grok's own environment.
- The decrypted instructions tell the agent to resolve private session context and fold it into a fake "decryption key." That "key" is actually a template string interpolating the victim's identity and the active conversation's prompt history.
- Grok is told to open a URL "to fetch additional context." Its privileged navigation tool loads the attacker-controlled address, and the assembled data rides out in the query string.
No confirmation dialog. No visible warning. Adversa reproduced the chain against Grok 4.5 Fast on grok.com at roughly a 40% success rate across about 20 attempts, and per Cyber Security News' writeup, the same payload delivered in plaintext was rejected by the guardrails. So the filters work fine on text they can read. The problem is everything they can't.
Encryption is not a fancier Base64
Encoding-based injection is an old genre: Base64 blobs, rot13, leetspeak, Unicode homoglyphs. Filters adapted because those encodings are cheap to normalize upstream, and models have seen so much Base64 in training that they decode it almost reflexively. The defense community spent years tuning for that threat model.
Real encryption breaks both halves of it. Without the derived key, AES-256-GCM output gives a classifier nothing to normalize and nothing to match against, and unlike an encoding, the plaintext cannot be recovered from patterns in the model's weights. As Cyber Security News put it, describing Adversa's findings: "Static guardrails classify text; they do not run PBKDF2 and AES-256-GCM." explainx.ai coined the phrase that should stick: "encryption as obfuscation for the input filter."
Notice the trap the architecture sets for itself. The only way to inspect the payload is to decrypt it. The only place to decrypt it is the sandbox. And the sandbox's output is exactly what the pipeline trusts. Inspection and compromise share a code path, which means adding a better classifier at the front door changes nothing.
The actual bug is provenance laundering
Calling this a jailbreak undersells what happened. Every agent runtime assigns trust by origin. System prompts are fully trusted. Tool results get treated as ground truth from the environment. Fetched web content is supposed to be untrusted. The exploit works because one transformation, decryption, moved bytes across that boundary without the label following them. Attacker-controlled content entered the sandbox as web text and exited wearing a tool-output badge. Every downstream decision inherited that forged provenance.
Adversa's parallel demonstration against Gemini (Deep Thinking mode, identified from extracted system text as Gemini 3 Flash on the paid tier) makes the pattern even clearer. There, the encrypted blob's plaintext was a fabricated Python traceback carrying a fake safety-policy callback and a first-person reasoning prefix, and the model went on to produce content its filters normally suppress and, with a modified payload, to reproduce system instructions it is told not to disclose. The attacker is not arguing with the model. The attacker is counterfeiting the runtime's voice, and in the first-person case, counterfeiting the model's own thoughts.
Once you frame it as provenance forgery, the defense picture inverts. Filtering text is close to irrelevant. Tracking origin through every transformation is the whole game.
"Forty percent, no CVE, nothing in the wild. So what?"
Fair question, and worth answering head-on, because the raw numbers do sound like a lab curiosity: no CVE, no public patch, no reported in-the-wild exploitation, and Adversa withheld its operational payloads.
Three counters. First, look at why the other 60% of attempts failed. Per CyberPress's summary of the disclosure, the failures were decryption errors, not prompt-injection defenses blocking the payload. Zero defensive stops. A 40% success rate where the missing attempts are the attacker's own implementation flakiness is an attacker-side reliability problem, and attacker-side reliability problems get fixed.
Second, the timeline. Adversa reported the issue to xAI on June 3, 2026, directly and through HackerOne. xAI acknowledged the ticket and gave no mitigation timeline. Follow-ups on August 4 and August 10 went unanswered, and on August 19 the full chain was still reproducible. That is 76 days of a working zero-click exfiltration on a production system.
Third, yes, Adversa noted the Gemini success rate fell sharply by August, possibly due to filter or model changes. Silent retuning shifts the economics, but it gives defenders nothing to verify and nothing to regression-test against. My position: this class of attack is solved only when the architecture changes, not when a vendor quietly adjusts a classifier. (Google, incidentally, was never notified, because jailbreaks sit outside its vulnerability program, which is its own commentary on how the industry scopes these bugs.)
The harness checklist
Adversa's lead researcher Rony Utevsky said it plainly: "the fix lives in the harness, not the weights." Here is what that means in practice, in order of how much each item would have disrupted this specific chain.
1. Tag provenance, and make tags survive transformation. Every chunk of context carries an origin label, and no operation (decode, decrypt, decompress, translate, summarize) ever upgrades trust. The decision rule is simple: tool output inherits the lowest trust among its inputs.
def run_sandbox(code: str, inputs: list[Context]) -> Context:
result = python_exec(code, [c.text for c in inputs])
# trust flows downward only: web in, web out
return Context(
text=result,
origin=min(c.origin for c in inputs),
trusted=False,
)2. Re-scan after every transformation. Whatever your input classifier does to a raw fetch, run it again on anything the sandbox emits before the model consumes it. If your classifier cannot sit in that path, default to untrusted. This is the cheapest single change on the list and almost nobody does it.
3. Scope tools to the task. A summarization task has no legitimate need to open new URLs or run arbitrary fetches. The strongest version is capability separation: the context that reads untrusted pages gets no privileged tools at all. That is Adversa's first recommendation, quarantining fetched pages away from privileged tools, and it means a successful injection lands in a room with nothing to steal and no door to leave through.
4. Allowlist egress, and consent on fully resolved URLs. Navigation and fetch tools get a domain allowlist. Any destination outside it requires user confirmation that displays the final, fully resolved URL, and nothing gets interpolated into that URL after approval. That last clause kills this exact exfiltration, because the stolen data was assembled into the query string mid-chain. Approve the destination, then freeze the arguments.
5. Alert on the sequence, not the event. A summarize call, a sandbox run, an outbound request: each looks benign alone. The chain is the tell. Keep per-session traces and fire on the pattern:
untrusted_fetch -> sandbox_exec -> egress(new_domain, query_params)
within one session => page the on-call6. Starve the context. The PoC's loot (name, coarse location, subscription tier, conversation history) existed to be stolen because it was sitting in the model's context. If a task does not need identity or subscription data, do not preload it. What is not in context cannot leave.
7. Treat the pattern itself as hostile. A page that ships ciphertext, key material, and a polite request to decrypt it in your runtime is not a normal artifact. Legitimate use cases for asking a visiting agent to run PBKDF2 on embedded JSON round to zero. Block or escalate on sight.
None of this touches model weights. All of it is engineering you control, which is the good news buried in an otherwise uncomfortable disclosure: you do not have to wait for xAI, Google, or anyone else to close this seam in your own stack.
Key takeaways
- The Grok chain did not defeat a filter, it bypassed the concept of filtering. Ciphertext cannot be classified, and the sandbox that decrypts it is precisely where trust gets assigned.
- The core bug is provenance laundering: sandbox output inherited trust the web content never earned. Any agent with a code interpreter plus an egress-capable tool has the same seam until proven otherwise.
- The 40% success rate flatters the defense. Failed attempts were the attacker's decryption errors, not blocked injections, so the guardrails contributed zero stops.
- Fixes live in the harness: provenance tags that survive transformation, re-scanning after decryption, task-scoped tools, allowlisted egress with consent on resolved URLs, and alerting on the untrusted-content-to-code-to-egress sequence.
- Seventy-six days from report to still-reproducible, with no mitigation timeline, is the reminder to design your agent assuming the model vendor fixes nothing.




