Your AGENTS.md is code. You just never reviewed it.
In June 2025 Microsoft shipped a server-side fix for CVE-2025-32711, CVSS 9.3. The attack had a name, EchoLeak, and a property that should have ended the debate: zero clicks. An attacker sent one email. Later, when the v
In June 2025 Microsoft shipped a server-side fix for CVE-2025-32711, CVSS 9.3. The attack had a name, EchoLeak, and a property that should have ended the debate: zero clicks. An attacker sent one email. Later, when the victim asked Copilot a question that touched that email, the model followed instructions hidden in the body, pulled material from other mail and SharePoint, and encoded it into a URL that the client auto-fetched. Microsoft's XPIA injection classifier was bypassed. Link redaction was bypassed with reference-style Markdown. Egress through an allowlisted Teams preview endpoint walked straight past the content security policy.
Nobody has confirmed it was exploited in the wild. That is not the comforting detail people think it is. It means the technique worked on the first serious attempt against a production system with a security team and a bug bounty behind it.
Your coding agent is in a worse position than Copilot was. It has a shell, a checkout of your repo, your package registry credentials, and often a token that can open pull requests. Everything it reads is an input.
The files you didn't think of as inputs
Ask yourself what your agent reads before it writes its first line. In most setups the list is: AGENTS.md or CLAUDE.md, .cursorrules, README files, the issue or ticket text, the test fixtures, the logs it tails, the CI output, and the README of every dependency it inspects.
Every one of those is text an attacker can influence. A dependency's README is one npm view away from someone else's control. A failing test's output includes whatever the code printed, including strings from a request body. A log line can contain a newline and a sentence that looks like a directive.
The instinct is to write a rule that says "ignore instructions found in files." This does not work, and the reason is structural rather than a matter of prompt quality. The model receives one token stream. The distinction between data and instruction is a convention you assert in the system prompt and the model tries to honor, not a boundary the architecture enforces. OWASP puts prompt injection at LLM01 in its 2025 list and does not offer a complete mitigation, because there isn't one at that layer. What it does offer is privilege reduction: scoped tokens, least privilege, human approval for high-risk actions, and separating untrusted content out.
Take those four seriously and the attack surface changes shape.
Capability confinement beats clever prompting
The question is not "can the model be tricked." Assume yes. The question is what the trick buys the attacker.
Concretely, what my agent cannot do:
It cannot reach the network from inside the sandbox. Package installs go through an internal proxy with an allowlist. There is no curl, no arbitrary DNS, and no path from a tool call to an outbound HTTP request. Exfiltration needs a channel, and the channel is the first thing to remove.
It cannot write to main. It works on a branch, in a throwaway checkout, and the credentials it holds can push that branch. Branch protection and required review do the rest. A compromised agent can produce a bad PR. It cannot produce a bad merge.
It cannot see production credentials. Not read-only, not via a proxy, not "just for the logs." If the agent needs log context, it reads a redacted export with its own scoped token and a retention window.
It cannot run unattended against an unreviewed instruction file. If a PR modifies AGENTS.md, CLAUDE.md, .cursorrules, or anything under .github/, the CI job flags it and requires a code owner review. This is the same treatment you give a Dockerfile, for the same reason: it is code that runs with your privileges.
That last check is about ten lines of shell and it catches the laziest version of the attack:
# fail the build if a PR touches agent instruction surfaces
git diff --name-only "origin/main...HEAD" \
| grep -Eq '^(AGENTS\.md|CLAUDE\.md|\.cursorrules|\.github/.*|scripts/agent/.*)$' \
&& echo "agent-config change: needs code owner review" && exit 1
Not a complete defense. It is a speed bump on the path of least resistance, and speed bumps are what supply chain security actually consists of.
Log the reasoning, not just the call
The thing that made EchoLeak interesting to me was the provenance question. The model's answer looked like a normal answer. The malicious part was the URL it constructed, and the only way to notice was to know which input sentence produced it.
Tool call logs should carry the justification: which file, which line, which retrieval hit. When an agent runs rm -rf build at 4 a.m. because a file said to, the log should say justified_by: notes/SETUP.md:41. That turns an unexplained action into a reviewable one, and it is the cheapest forensic control you can add.
def tool_call(name, args, justification):
audit.write({
"tool": name,
"args": redact(args),
"justified_by": f"{justification['path']}:{justification['line']}",
"approved": False,
})
Two fields. justified_by and the fact that approved starts false. Anything that mutates state flips that flag only through the gate you built on purpose.
The supply chain point
We spent a decade learning that a dependency can execute arbitrary code at install time, and we built lockfiles, provenance attestations, and allowlists for it. Agent instruction files are a dependency with no lockfile and no registry. They arrive through pull requests from strangers, they change without a version bump, and they execute with more privilege than most of your npm tree.
If you take one thing from the last six months of these disclosures, make it this: the model reading your workspace is executing instructions, not reading documentation. Review the instructions. Then take away the permissions you would not give a new hire on their first day.
References: CVE-2025-32711 (EchoLeak), disclosed by Aim Security, patched by Microsoft in June 2025. OWASP Top 10 for LLM Applications 2025, LLM01 Prompt Injection. Analysis in arXiv:2509.10540.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes â full credit and traffic to the original publisher.