CamoLeak turned GitHub Copilot Chat into a private-repo exfiltration tool
Legit Security researcher Omer Mayraz disclosed CamoLeak, a critical flaw rated CVSS 9.6 in GitHub Copilot Chat. An attacker hides instructions in invisible Markdown comments inside a pull request; when a victim asks Copilot Chat about that PR, the assistant ingests the hidden text, searches the victim's private repositories for secrets and source, and smuggles the data out one character at a time through pre-signed image URLs routed via GitHub's own Camo image proxy. Because the traffic flows through GitHub's trusted infrastructure, it blends into normal image loading. GitHub mitigated it by disabling image rendering in Copilot Chat around August 14, 2025, after a June 2025 HackerOne report; public disclosure followed in October 2025. The reported attack is a proof of concept with no confirmed real-world victims.
Incident Details
The comment nobody could see, except the AI
GitHub Copilot Chat is the conversational version of GitHub's coding assistant. You can ask it to explain a pull request, summarize changes, or hunt through your repositories for context. To do that usefully, it reads. It reads the PR, the diff, the surrounding code, and crucially the parts of a pull request that a human reviewer never looks at. That last detail is where CamoLeak lives.
Omer Mayraz, a researcher at Legit Security, disclosed CamoLeak in October 2025. The writeup rated it CVSS 9.6, which is firmly in the "drop what you are doing" tier of severity. The attack chains two ideas that are individually understood and collectively alarming: hide instructions where only the AI will read them, then exfiltrate stolen data through GitHub's own trusted plumbing.
Markdown, the formatting language GitHub uses everywhere, supports comments of the form <!-- like this -->. Those comments do not render in the normal web view. A human reviewing a pull request sees a clean, ordinary description. Copilot Chat, processing the underlying raw Markdown, sees the hidden comment too - and treats whatever is written there as part of its instructions. So an attacker opens a pull request against a repository, packs a malicious prompt into an invisible comment, and waits. When the victim later asks Copilot Chat anything about that PR, the assistant quietly folds the attacker's hidden instructions into its task.
This is indirect prompt injection: the attacker never talks to the victim's Copilot directly. They poison a document the victim will eventually ask the AI to read. The model cannot reliably tell the difference between "content I should summarize" and "commands I should obey," because to a language model both are just text in the context window.
Stealing data through an image proxy, one letter at a time
Getting Copilot to go rummage through the victim's private repositories for API keys, tokens, and source code is the easy half. The hard half is getting that loot back out. Copilot Chat runs behind a Content Security Policy, a browser rule that restricts where the page can send requests. You cannot simply tell the AI to POST the secrets to evil-server.example. The browser would block it.
Mayraz's exfiltration route is the part of CamoLeak worth slowing down for, because it is genuinely inventive. GitHub renders images in Markdown through a proxy called Camo (served from camo.githubusercontent.com). When you embed an external image, GitHub rewrites the URL into a signed Camo URL - it adds an HMAC signature so that only GitHub-approved image URLs load, which is itself a security feature meant to protect user privacy and block sketchy external content.
The researcher turned that protection into the leak. Ahead of time, he pre-generated a dictionary of valid, signed Camo URLs - one for every letter, digit, and symbol that might appear in stolen source code. Each URL pointed at a tiny one-pixel image on a server he controlled, and each one was distinct. Then he instructed Copilot to render the stolen data as a sequence of these images, effectively spelling out the secrets character by character. Every character rendered triggered a separate request to its corresponding URL on the attacker's server. By watching which images were requested and in what order, the attacker reconstructs the exfiltrated text one letter at a time.
The elegance, from the attacker's point of view, is that every one of those requests flows through camo.githubusercontent.com - GitHub's own trusted domain. To any monitoring tool, it looks like Copilot Chat is loading images, which is exactly the boring thing Copilot Chat does. There is no suspicious outbound connection to flag. The data walks out the front door wearing GitHub's uniform.
What it could pull, and what it actually pulled
In the proof-of-concept, Legit Security demonstrated extracting real categories of sensitive material from private repositories: AWS keys, security tokens, and descriptions of undisclosed vulnerabilities. That last item is a special kind of bad - a private repo where a team is quietly working on an unannounced security fix is precisely the sort of thing you do not want an attacker reading early.
This was a researcher's demonstration. There is no public evidence that CamoLeak was used against real GitHub users before it was fixed. The data extraction was proven against the researcher's own test setup, by observing the requests hit his server. Treat this as a documented critical hazard with proven feasibility, not a confirmed breach with victims.
The CVE attribution
Several secondary outlets attached the identifier CVE-2025-59145 to CamoLeak. Be careful with that. The primary Legit Security writeup states the CVSS 9.6 rating but does not itself cite a CVE number, and at least one analysis flagged that the public NVD record for CVE-2025-59145 describes an unrelated npm package compromise, not this Copilot Chat flaw. So the CVSS 9.6 severity is well supported across sources; the specific CVE attribution is shakier and should not be repeated as settled fact. When the primary source declines to name a CVE and the cited number points elsewhere in the official database, the careful move is to report the severity and skip the dubious identifier.
GitHub's fix
GitHub received the report through HackerOne in June 2025 and mitigated the issue by disabling image rendering in Copilot Chat around August 14, 2025, which severs the Camo-based exfiltration channel by removing the AI's ability to render the images that carried the data. Public disclosure came in October 2025, after the fix was in place. Cutting off image rendering kills this specific data path cleanly.
The graveyard lesson
CamoLeak earns its place because it is a near-perfect illustration of the agentic-AI security problem in one loop. Give an assistant broad read access to private data. Let it ingest untrusted text from places humans do not inspect. Then give it a way to render content, which is also a way to make network requests. The attacker does not need to break cryptography or find a memory bug. They write a comment nobody can see and let the helpful AI do the rest.
The deeper discomfort is that two reasonable security features collided. Hiding implementation notes in Markdown comments is normal. Signing image URLs through a proxy to protect privacy is a defense. CamoLeak chained them into a leak. When you wire a language model into a system, every channel it can read becomes an input vector and every channel it can write becomes an exfiltration vector, no matter how innocent each one looked on its own.
Discussion