Skip to content
senn-techsenn-tech
Back to blog
GrokSecurity
Security and data protection2026-11-05· By Franz Senn

Prompt injection: why we limit what our AI agents are allowed to do

In short: Adversa AI describes a prompt injection in which the instruction sits on a web page as ciphertext. The agent decrypts it itself and follows it, while a text filter sees only noise. With Copilot CLI one fetched link was enough to pull a .env.prod file in 28 seconds. What decides the outcome is the rights the agent holds. On our side, access to the tools is restricted, and we have not measured any filter for outgoing web requests on the agent host. The post ends with a ten-minute check for your own agent.

Anyone who lets an AI agent read a web page hands the author of that page a share of the order book. That is not new, but in summer and autumn 2026 the security firm Adversa AI showed that a text filter no longer closes this path. This post sums up what Adversa and Ars Technica document, then describes what we have on record about our own agents and what we measured on 5 November. Much of it is incomplete, and we say where.

Prompt injection is an attack in which an AI agent treats text from an untrusted source, such as a web page, a mail or a tool output, as an order from the user and carries it out. How much damage follows depends on the agent's rights: everything it may read, run and send out, an attacker can use as well.

What Adversa and Ars Technica document

Adversa calls the method Cryptographic Context Injection. The instruction sits on the page as AES-256-GCM ciphertext, next to the key material and a request to decrypt it with Python. A plaintext filter cannot read the content, because that would take running the decryption. The agent runs it in its own code environment, and the result shows up as the output of its own program. There, according to Adversa, it is no longer handled as foreign input. For Copilot CLI, Adversa reports that the same instructions in plaintext were refused. Ars Technica summarizes on 20 August that language models cannot fix the root of prompt injection, so vendors build guardrails that the next attack goes around. That is the author's assessment.

Copilot case as Adversa describes it: from the fetched link to the sent .env.prodPage with ciphertextkey sits next to itAgent fetches pageautopilot modeDecryptionwith Python, in the agentOutput counts as ownno longer foreign textRead file and send28 seconds in total
Schematic of the chain Adversa describes, not a measurement of ours. (source: Adversa AI, 6 October 2026)

Three cases follow.

With Grok (report of 20 August), a request to summarize a page makes the agent, according to Adversa, build a supposed key that actually holds the user's name, location, plan and chat history, and append it to an attacker's URL. The report to xAI went out on 3 June, and by Adversa's account the follow-ups on 4 and 10 August went unanswered. On 19 August the attack still reproduced.

With Gemini, the decrypted text looks like a Python traceback and tells the model to act on the error message if the code fails. According to Adversa this produced content Gemini normally suppresses and revealed its system instructions. Over the summer the success rate dropped, and the cause is unknown.

With GitHub Copilot CLI (report of 6 October), the user has the agent read a page in autopilot mode. After 28 seconds the contents of a .env.prod are in the attacker's log, and the agent's own summary says something else. Which model handles the session matters: one model ran the chain in 50 percent of the attempts, two others refused. With automatic model selection the user cannot see which one they get. GitHub accepted the finding as valid but did not rate it a vulnerability, because the user had given the agent the page and full permissions.

Logo of GitHub Copilot
GitHub Copilot CLI is the tool in the case of 6 October. (Quelle: Simple Icons 16.36.0, githubcopilot.svg (MIT); trademark: GitHub)

Adversa sells an agent-security platform. The measurements are the vendor's statements, and we did not reproduce them. A figure like "20 attempts, 40 percent", which we came across in connection with Grok, appears in neither Adversa nor Ars and is not used here.

Five rules, and where we stand

From this Adversa derives five rules for the environment around the agent: process untrusted content in a context without tools and credentials, release outgoing actions only with resolved arguments, record tool calls per session, alert on sequences instead of single texts, and ask vendors how data and instructions are kept apart. We compared these rules with our notes and measurements.

Adversa ruleWhat we have on recordSource, date
Process foreign text without rightsFor the mail checker the rule is that a manipulated text may neither silence nor steer the verdict, and a missing verdict never counts as a pass. For the planned inbox in the personal assistant, sanitizing and testing are listed as a precondition.Notes of 4 October and 17 August
Limit outgoing actionsThe agents' mail goes only to three addresses from a list that lives on the host, out of the agent's reach. For web requests no egress filter is documented.Note of 17 September, measurement below
Record tool callsPrompts that pass through the LiteLLM gateway are stored in Postgres. Whether the resolved tool arguments of every session are in there, we have not checked.Note of 7 August
Alert on sequencesNothing in our records.As of 5 November
Ask vendors about separationOpen, we have no list.As of 5 November

The filter in the gateway matches patterns. A note from October records that it blocked the phrase "Ignore previous instructions" and let "Ignore all previous instructions" through. In August it turned out that six of six organic hits were false alarms, for example a skill catalog with the word "jailbreak" in a description. A hit in a tool result stayed in the session for good and killed it. Writing patterns for imperatives instead of vocabulary causes less trouble, but against encrypted text a pattern match does not help, going by Adversa's description.

What we measured on 5 November

We measured read-only, with iptables -S over SSH, on 5 November 2026 at 20:06 UTC, on two Linux hosts: the host for LibreChat, LiteLLM and the MCP sidecars, and the host for the dsh agent.

MeasurementResultUnitMeasurement host
Gate in front of the seven dsh sidecars1 rule: everything except the agent host is droppedrulessidecar host, chain DOCKER-USER
Gate in front of the LiteLLM port17 allowed sources, everything else logged and dropped according to the scriptsourcessame host
Gate in front of the crawl sidecar6 allowed sourcessourcessame host
Egress filter on the agent hostchain DOCKER-USER empty, OUTPUT on ACCEPTrulesagent host

A comment in the gateway's script records that the LiteLLM port and the crawl sidecar were open without authentication to the whole LAN until the audit of 26 October. The gate was set after that audit and protects the entrances. It says nothing about the question "where may the agent send data when a page it has read tells it to?", and that is exactly what the attack targets. On the agent host we found no filter for outgoing connections. Whether a proxy or a rule inside the container sits in between, we did not investigate.

On rights, according to our notes: the Proxmox MCP token was not read-only when we checked on 3 August: it held rights to create, delete, stop and roll back VMs on all nodes. The note records the PVEAuditor role as the fix. The operator profile in the MCP server only gates at application level, and the token sets the boundary. A later note on the Telegram agent lists the same token. Whether it has been replaced since, we did not check for this post. For the dsh agent, a note of 5 October records that the container has the fleet's root SSH keys mounted, and the agent CLI has run as root on the host since 29 September. Both were recorded as open decisions on 5 October.

Still to measure

We did not measure three things for this post. We name the method, there is no result yet.

  1. Outgoing traffic of the agent: on the agent host look at ip route, proxy variables in the container and rules in FORWARD and DOCKER-FORWARD, then have a person send a single request from the container to a test server of our own and count it in the test server's log. The agent itself gets no task for this.
  2. Rights of the Proxmox token: query GET /access/permissions with the token for every path and compare against the write privileges, as described in the note of 3 August.
  3. Traces per session: read the field proxy_server_request of a dsh session in LiteLLM_SpendLogs and check whether tool calls with resolved arguments are in it. According to our note the field messages stays empty there.

We will not replay an attack with an encrypted instruction against our agents.

The ten-minute check

  1. List every agent that reads web pages, mails or tickets (two minutes).
  2. Next to each, write which keys, files and networks the same agent can reach (three minutes).
  3. For every row that has both, remove one right: separate the reading or take away the credentials (three minutes).
  4. Check by hand whether the agent may send data out without asking, and write down the result (two minutes).

For the implementation, our work on AI on your own hardware can help. The earlier history of this attack class is in Agentjacking: when the error message hijacks the AI agent, and more posts on the subject are collected under Security and data protection.

What is documented and what is open

Documented, because we read the sources on 5 November: the structure of the method, the three cases with their report dates, the 28 seconds, the 50 percent for one Copilot model and GitHub's position, all as statements by Adversa, and for Grok additionally put in context by Ars Technica (we could only read its header section). Documented by our own measurement of 5 November: the gate rules and the missing egress filter on the agent host.

Open: whether xAI, Google and GitHub have changed anything since the reports, whether Adversa's figures can be reproduced independently, and the three points under "Still to measure".

Further Reading

Sources last checked: 2026-11-05

Questions?
What did Adversa AI show against Copilot CLI?+

According to Adversa, GitHub Copilot CLI in autopilot mode reads the file .env.prod after fetching a prepared web page and sends its contents to an attacker, in 28 seconds and without asking. It depends on the model: one model ran the chain in 50 percent of the runs, two others refused. GitHub did not classify the finding as a vulnerability. These are Adversa's statements, we did not reproduce the attack.

Does a filter help against prompt injection?+

Only partly. Our own filter in LiteLLM blocked the phrase Ignore previous instructions, according to a note from October, but let Ignore all previous instructions through. Adversa also describes that encrypted text never triggers a text filter in the first place. Filters stay useful as an extra layer, the limit is set by the agent's rights.

What is the first step for a mid-sized company?+

Keep a list: which agent reads text from outside, and which credentials does the same agent hold? Where both meet, separate the reading or the rights. The ten-minute check at the end of this post walks through it.