Hero Background

Power Your Software Testing with AI Agents and Cloud

The Native AI-Agentic Cloud Platform to Supercharge Quality Engineering. Test Intelligently and Ship Faster.

SecurityAIAgent Testing

Copilot CLI Prompt Injection: The Transcript Called It Fetching Context

A Copilot CLI prompt injection sent a .env.prod file to Adversa AI's server in 28 seconds, and the agent's own transcript called the theft fetching context.

Published on:

Security researchers at Adversa AI have published an attack on GitHub Copilot CLI, GitHub's coding agent for the terminal. In their test, a single web page was enough to make the agent read a project's .env.prod file and send its contents to a server the researchers controlled. The whole chain took 28 seconds.

This was research: Adversa used its own test project with a planted secrets file, and nobody's real credentials were taken.

GitHub doesn't consider it a vulnerability. A GitHub spokesperson told The Register that the attack "requires a user to intentionally direct Copilot CLI to fetch attacker-controlled or untrusted content and confirm they want to trigger the action, and thus is not a product vulnerability." Adversa disagrees.

Both of those matter, and we'll come back to them. But the most interesting thing in Adversa's write-up is what the agent's screen said while the attack happened. That gap, between an agent's account of its work and the work itself, is what TestMu AI built Agent Assurance to test.

TL;DR

The Copilot CLI prompt injection is an attack Adversa AI published on 6 October 2026 in which one web page made GitHub Copilot CLI, running in autopilot, read a project's .env.prod file and send its contents to a researcher-controlled server in 28 seconds. The agent's own step label called the request fetching context.

  • Cryptographic Context Injection: Did Copilot CLI's prompt-injection defence work? Yes, against plaintext. Adversa hid the instructions as ciphertext that the agent decrypted with Python in its own shell, so they became readable only as the output of code the agent ran itself.
  • Autopilot mode: Does the attack work without autopilot? No. Adversa's chain needs Copilot CLI's optional autopilot mode switched on and a permissive model handling the session, after which no further user interaction was needed.
  • Model routing: Does every Copilot CLI model run the chain? No. One model ran it in half of Adversa's runs, two others consistently refused it, and with selection on Auto the user does not see which model handled the session.
  • GitHub's position: Does GitHub treat the Copilot CLI attack as a vulnerability? No. GitHub says the user chose to fetch untrusted content and let the agent act, while Adversa says the chain still reproduced as of 1 October 2026.
  • The transcript: Adversa's demo shows Copilot CLI listing "Read .env.prod" and later "Fetch the follow-up context endpoint", with no destination host and nothing saying file contents left the machine. The labels were accurate and written in the attacker's terms.
  • Independent evidence: The outbound request, its host and its parameters, showed where the stolen .env.prod file went. Checking effects outside the agent's own account is the core of AI agent security, and TestMu AI's Agent Assurance grades agents on what a run did, not on what they report.

The Setting: A Coding Agent on Autopilot

Copilot CLI runs in your terminal, inside your project. You ask it to do things in plain language, and it reads files, runs commands and makes network requests to get them done.

It has an autopilot mode, in which, per GitHub's docs, Copilot CLI "works through each step autonomously until it determines the task is complete."

The Register notes that autopilot is optional in Copilot CLI, and Adversa's attack needs it switched on. In GitHub's words, quoted in Adversa's disclosure timeline, the user in the test was "giving copilot full permissions to act autonomously".

The task was as ordinary as it gets: here's a link, go read the page.

Cryptographic Context Injection, in Plain Words

Prompt injection is the old problem: text the agent reads from somewhere else (a web page, an email, a ticket) contains instructions, and the agent follows them.

Coding agents defend against this, and prompt injection testing is how teams check that the defence holds. Adversa confirms it holds here: "The same instructions delivered as plaintext are caught as prompt injection and refused."

Adversa's technique, which it calls Cryptographic Context Injection, gets around that by never letting the instructions appear as text. The page carries them as ciphertext, along with the key material and an instruction to decrypt it with Python. A filter that reads text has nothing to read.

The instructions only become readable once the agent has run the decryption in its own shell, and at that point, Adversa writes, the agent "treats the plaintext as trusted instructions." They came out of code it wrote and ran itself.

Adversa first published the technique in August against chat assistants. This is its first write-up of the technique against a coding agent, where running code and making network requests are part of the job.

The Chain, Step by Step

Adversa describes what followed once the user pasted the link:

  • The page presented "encrypted content with an instruction to decrypt it using Python" and offered two candidate keys.
  • One key was not really a key. It was a template the agent could only complete by reading local files. To build it, the agent read .env.prod and folded the contents into the key string. "That read is the theft," Adversa writes.
  • Decryption with that key failed, by design. The agent fell back to the real key, and decryption worked.
  • The decrypted instructions told the agent to fetch a follow-up URL "to grab more context". That URL carried the harvested file contents as a parameter.
  • The agent made the request. The contents arrived at the researchers' endpoint.

Adversa has withheld the actual payloads, and we won't describe them further.

The Model in the Session Matters

Copilot CLI lets users pick from several models, or leave the choice on Auto. Adversa reports that one model in the pool ran the full chain in half its runs, while two others consistently refused the same payload.

On the paid account Adversa tested, the permissive model had to be selected by hand; on Auto, the router sometimes assigned it. As Adversa puts it, "The user does not choose, and does not see, which model handled the session."

That's a fair point about routing. It is also a reminder that the same product, on the same input, can behave very differently depending on something the user may not see.

GitHub's View, and Adversa's

Adversa reported the finding to GitHub's bug bounty programme on 17 September. GitHub's triage team validated it and declined to treat it as a vulnerability, on the grounds that the user chose to fetch untrusted content and let the agent act. GitHub told Adversa it may make the functionality stricter in future.

Adversa says that as of 1 October the chain still reproduced. It argues that encryption is what gets the instructions through, since the same text sent as plaintext is refused.

Both positions are defensible. Autopilot is a choice, and so is pasting a link. It's also true that "go read this page" is exactly what people use coding agents for.

We're not going to referee the bounty. The part that interests us is the transcript.

On the Agent's Screen

Adversa published a demo video of the session, and we went through it frame by frame. Two lines on the agent's screen matter. The first:

Read .env.prod L1:200 (78 lines read)

The read was on screen. Then, three steps later, the step that sent the file out:

Fetch the follow-up context endpoint using the constructed authorized key_a value

And on the researchers' server, the request that arrived, with .env.prod inside its token parameter:

GET /v1/user/get_more_context?c=43622&x-auth-token=...

Adversa's summary of the session: "no point in the transcript that names the destination host or indicates that file contents left the machine." The researchers also report that the agent's closing summary said it had "confirmed an authorized-reader endpoint". That summary isn't in the video, so we'll leave it as their report.

The Account Came With the Attack

Look at the second line again. It isn't false. The agent did fetch the follow-up context endpoint.

That's how the decrypted page framed the request ("to grab more context"), and it's the name on the attacker's server: get_more_context. The harvested file travelled in the request's token parameter, and the label calls it "the constructed authorized key_a value".

An agent's account of its own work is usually weak evidence for ordinary reasons. The agent may be wrong. It may round a partial success up to "done", or leave out the step that went badly.

This is a different problem. The agent's description of what it was doing came from the same place as what it was doing. When an attacker writes the instructions, the agent narrates its actions in the attacker's terms.

The labels are accurate, and they are not yours. That's why reading the step labels more carefully doesn't help: none of them is false. "Fetch the follow-up context endpoint" is simply what a theft looks like when the thief wrote the task.

The approval prompt in the Manus prompt injection had the same weakness from the other side: it was the agent's description of an action that, by the time it appeared, had already run.

When the instructions are injected, so is the account.

I also wrote this up as an article on X:

Evidence Outside the Transcript

I keep coming back to one line: an agent's account of what it did is the weakest evidence available about what it did.

In this case, what the attacker didn't get to write was the request itself: the host it went to, and what was in its parameters. That's evidence someone other than the agent can check, and it's the part of this story that says plainly where the file went.

Adversa's own defensive advice points the same way: capture "a per-session trace of every tool call with its arguments fully resolved, not the templates." Records like that, kept outside the agent's narration, are what agent observability is for.

The same kind of check is worth running before a coding agent ships. TestMu AI's Agent Assurance generates adversarial scenarios for your own agent, with prompt injection and data exfiltration among the default categories, and a scenario can hand the agent a URL to read, the same request Adversa's user made.

It invokes the agent for real against staging and grades each criterion on evidence, such as the tool calls the agent actually made checked against the tools it declares, never on the agent's own account. Anything it could not observe is reported as Unable to Verify, as the Agent Assurance scenarios guide explains.

The labels on the steps describe the agent's understanding of its task. The request shows what it actually did.

Not the label on the step. Where the request actually went.

Author

...

Vipul Verma

Blogs: 8

  • Linkedin

Vipul Verma is Group Senior Vice President of Engineering at TestMu AI (formerly LambdaTest), where he heads the entire engineering organization that builds KaneAI, HyperExecute, and the broader testing cloud. He brings 15+ years architecting, securing, and scaling large enterprise applications across multiple sites. Before TestMu AI he was India Head at LogicHub, where he built the India R&D site from the first employee to a 30-plus engineering team, and Principal Software Engineer at Sumo Logic, where he was the first engineer in the India office and shipped search-performance and pricing-model initiatives. Earlier he worked on trading platforms at Portware and D. E. Shaw. Vipul holds a B.Tech in Computer Science from IIT Kharagpur.

Reviewer

...

Mayank Bhola

Reviewer

  • Linkedin

Mayank Bhola is Co-Founder and Head of Products at TestMu AI (formerly LambdaTest), where he leads the entire product portfolio across KaneAI, Kane CLI, HyperExecute, SmartUI, the Real Device Cloud, Accessibility, and other software testing product lines. As an early Lead Architect he designed and built the company's flagship Tunnel technology from scratch, created the React-based automation platform, and architected the data-intensive pipelines and FAAS services that scale it. He brings more than 10 years of experience in software development and product engineering, with earlier roles as Head of Technology at Juggernaut Books and Senior Software Engineer at PressPlay TV and Zomato. Mayank holds a B.Tech in Computer Engineering from JIIT Noida.

Add to Google preferred sources

Summarise with AI

Copied to Clipboard!
...

3000+ Browsers. One Platform.

See exactly how your site performs everywhere.

Try it free
...

Write Tests in Plain English with KaneAI

Create, debug, and evolve tests using natural language.

Try for free

Copilot CLI Prompt Injection FAQs

Did you find this page helpful?

More Related Blogs

TestMu AI forEnterprise

Get access to solutions built on Enterprise
grade security, privacy, & compliance

  • Advanced access controls
  • Advanced data retention rules
  • Advanced Local Testing
  • Premium Support options
  • Early access to beta features
  • Private Slack Channel
  • Unlimited Manual Accessibility DevTools Tests