Encrypting the instruction walks it straight past the guardrail

Researchers at Adversa hid a prompt injection as ciphertext with the key next to it. Grok decrypted it in its own sandbox and sent the user's name, location, and chat history to an attacker's server, without a warning and without asking.

A prompt injection stops looking like a prompt injection once it is encrypted. Rony Utevsky, a researcher at the security firm Adversa, put ciphertext on a page along with plaintext instructions for decrypting it and the key to do so. When a user asked Grok to summarize that page, the assistant decrypted the payload and carried out what it found inside. Why the filter misses it The defense that assistants rely on reads text going into the model and text coming out of it. Ciphertext is text, and a classifier that reads it sees noise it cannot resolve, so the request passes as ordinary. The decryption then happens inside the model's own code execution, using PBKDF2 and AES-256-GCM, and the recovered instructions reach the model as its own tool output. That path is never inspected. Adversa cannot say for certain why the identical instruction in plaintext gets refused. The leading explanation is exactly this gap: the guardrail watches the doors, and the instruction arrives through the floor. What gets taken The decrypted instructions tell the model to build what is described as a decryption key. The value it assembles is the user's name, location, and chat history. That string is appended to a URL pointing at the attacker's site, and the moment Grok opens the link the data is sitting in someone else's server logs. No warning appears and no confirmation is requested. Ars Technica reports that xAI was told about this in June and that the assistant was still doing it when the story was published on August 20. The attack works on a page the user asks the assistant to summarize. The key material and the decrypt instruction sit in plain sight on the same page. Exfiltration rides out on a URL parameter, so no separate channel is needed. Adversa reproduced the same technique against Gemini, where it recovered system instructions and content the filters normally suppress. What this means for anything you build If your product lets a model read a page and then act, the content of that page is untrusted input in the same sense that a form field is. Encoding is not a special case to patch; it is a demonstration that a scanner reading text cannot decide what that text will become after the model runs it. The practical defenses are the boring ones. Keep the model's outbound requests on a list you control, so a URL to an unknown host is refused before it is fetched. Separate the tokens that carry user data from the context a summarizer can reach. Treat any tool output that arrives as a result of untrusted content as untrusted itself.