Adversa AI says an encrypted web page made Copilot CLI read .env.prod and leak it. GitHub validated the behavior but issued no CVE and no bounty.
Adversa AI researchers showed that GitHub Copilot CLI, running in autopilot mode with a permissive model, can be steered by a single web page into reading local secret files and sending them to an attacker. GitHub's bug bounty triage validated the behaviour but declined to treat it as a vulnerability. There is no CVE and no bounty. The exposure is narrower than the headline: autopilot with broad permissions granted, a permissive model, and untrusted content. Adversa says the chain still reproduced as of 1 October 2026.
What Adversa found
Adversa calls the technique Cryptographic Context Injection (CCI). The malicious instructions are shipped as ciphertext, alongside key material and an instruction to decrypt them with Python. The agent runs the decryption in its own code-execution runtime, so the plaintext first appears as output of code the agent just ran. Adversa's argument is that content classifiers read text and do not execute ciphers, so there is no inspectable string to block, and the agent then treats the result as its own context.
The attack chain
Per Adversa's write-up, the user runs Copilot CLI in a project directory and asks it to fetch one URL. Then:
- The page presents encrypted content and tells the agent to decrypt it with Python. It offers two candidate keys.
- One key is genuine. The other is a template that cannot be completed without local file contents.
- To build the templated key, the agent reads the targeted files, such as
.env.prod, and folds them into the key string. Adversa says the files can sit outside the working directory, and the target pattern lives inside the payload. The read is the theft. - Decryption with that key fails by design. The agent falls back to the real key and succeeds.
- The decrypted second stage tells the agent to fetch a follow-up URL "to grab more context", with the harvested contents as a request parameter. The secrets reach the attacker's log (compare how SalesBleed pulled Agentforce data out of a CRM).
Adversa reports 28 seconds for the full chain, with no confirmation prompt and no point in the transcript naming the destination host or showing that file contents left the machine. The agent's closing summary said it had "confirmed an authorized-reader endpoint". The 28-second figure comes from Adversa's own demonstration and should be read as one run, not an average.
Conditions and the model lottery
Adversa states two requirements: the CLI in autopilot mode, and a permissive model. It says it is not claiming a confirmation-prompt bypass. In its words, the controls that would bound the attack are opt-in and off by default in autopilot, so the only remaining barrier is the model's own refusal behaviour (we covered a similar gap in Ollama's agent mode approvals).
That barrier varied by model. Microsoft's mai-code-1.1-flash executed the full chain in 50% of Adversa's runs. Two GPT-5.6 models offered in Copilot consistently refused the identical payload. Adversa has not published the number of runs behind the 50% figure or named the GPT-5.6 variants, so the rate is a rough indication only.
Model choice is not always the user's. On the paid account Adversa tested, the vulnerable model was not the default and had to be selected manually. On an account left on Auto routing, the router assigned it on some sessions and a safe model on others. Researcher Rony Utevsky calls this a "model lottery".
GitHub's position, and where the two accounts differ
Adversa reported the issue through GitHub's bug bounty program on 17 September 2026. By 1 October, Adversa says, GitHub's triage team had validated the finding but declined to treat it as a vulnerability, saying the user "explicitly asked Copilot CLI to fetch attacker-controlled content while giving copilot full permissions to act autonomously". Adversa adds that GitHub said it may make the functionality stricter in future but had nothing to announce, and ruled the report ineligible for the bounty. There is no CVE.
A GitHub spokesperson gave The Register this statement: "GitHub values the contributions of our security research community and is committed to investigating reported security issues. After investigating, we determined this 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. While this is not a security issue with the product itself, we are always looking for opportunities to improve our products."
Adversa disagrees with the risk assessment. Its argument is that Copilot's own refusal behavior defeats these instructions in plaintext, encryption is the only thing that gets them through, and the user is shown no destination and no sign that files left the machine. The user asked for a page to be fetched, not for local files to be read and sent out.
The accounts differ on one point. GitHub's statement speaks of the user confirming the action; Adversa's scenario is autopilot, where it reports no confirmation after the initial request. GitHub's documentation goes some way to explaining the gap, and this is our reading of it. Its Allowing and denying tool use page says read-only operations such as searching and reading files are allowed automatically, while tools "such as … accessing URLs—require your explicit approval". By default, then, the exfiltration fetch would prompt or, under autopilot with manual approval, be automatically denied. Reading .env.prod inside the working directory needs no approval at all. The fetch goes through silently only if the user has granted URL permission with --allow-all-urls, --allow-all or --yolo, or approved the domain permanently. That is what GitHub's "full permissions" and "confirm" wording points to. Adversa's counter-point stands: granting broad permissions is not consent to send local files to a host the user never saw.
No in-the-wild exploitation has been reported in the sources we reviewed; this is a demonstrated attack chain, not a known compromise. For enterprises that track vendor advisories, the practical effect of "not a vulnerability" is that there is no CVE to watch and no scheduled fix.
GitHub's documentation is consistent with its stance. Its autopilot page says you "will get the best results from autopilot mode if you enable all permissions", while warning that this lets the CLI make any change it deems necessary. --allow-all (alias --yolo) combines --allow-all-tools, --allow-all-paths and --allow-all-urls, and the docs strongly recommend using such options only in an isolated environment. The About Copilot CLI page says that "If you use an automatic approval option such as --allow-all-tools", Copilot has the same file access as the user, and that "Scoping of permissions is heuristic and GitHub does not guarantee that all files outside trusted directories will be protected". That last line supports Adversa's point about reads outside the working directory.
What defenders should do
- Do not run autopilot with
--allow-allor--yoloon a machine that holds production secrets. Use/sandbox enablefor a local sandbox or a cloud sandbox, as GitHub's docs advise, and never put the flags in a startup alias. - Use
--deny-toolrules, which win over allow-all, and ask Copilot administrators to block the permissive flags on Business and Enterprise. - For sessions that do not need the web, start with
--excluded-tools='web_fetch, web_search'. - Do not approve URL domains permanently. Review
allowedUrlsin~/.copilot/settings.json, and run/reset-allowed-toolsto revoke grants made in a session. - Keep
.env.prodand similar credentials out of any directory or account the agent can read. - Pin the model rather than leaving it on Auto, and treat the choice as a security setting.
- Capture per-session traces of tool calls with fully resolved arguments. Adversa advises alerting on the sequence: untrusted content enters, code runs, local files are read, then an unrelated host is contacted.
- Gate outbound requests and writes outside the workspace; in unattended runs, deny by default.
Caveats
Adversa sells a coding-agent security product and says its platform stopped the same chain when it reproduced it against an instrumented coding agent. That was its own test, not Copilot CLI, and Adversa has a commercial interest. Payloads are withheld, so independent reproduction is not possible from the public material. Run counts are unpublished.
And GitHub's reading is not unreasonable on its face: its own documentation says autopilot works best with all permissions enabled and tells users to run such modes in isolated environments. The dispute is whether a model that refuses plaintext instructions but obeys the same ones after decryption is a product flaw or a user-configuration risk.
Sources
- Adversa AI: https://adversa.ai/blog/cryptographic-context-injection-github-copilot/
- CSO Online: https://www.csoonline.com/article/4231763/encrypted-instructions-trick-copilot-cli-to-spill-dev-secrets.html
- The Register: https://www.theregister.com/ai-and-ml/2026/10/06/zombie-instructions-on-carefully-constructed-web-pages-could-trick-github-copilot-cli-into-sharing-secrets/5301206
- GitHub Docs, autopilot: https://docs.github.com/en/copilot/concepts/agents/copilot-cli/autopilot
- GitHub Docs, allowing tools: https://docs.github.com/en/copilot/how-tos/copilot-cli/allowing-tools
- GitHub Docs, about Copilot CLI: https://docs.github.com/en/copilot/concepts/agents/copilot-cli/about-copilot-cli