Get the latest, first
arrowBlog
Indirect Prompt Injection Examples: The Patch Won’t Transfer

Indirect Prompt Injection Examples: The Patch Won’t Transfer

Aug 17, 2026

Yossi Ben Naim
VP of Product Management

Every well-documented indirect prompt injection example is a vendor product with a CVE number and a patch at the end.

The mechanics transfer to your environment exactly. The remediation does not. Nobody is shipping you a fix for the agent your platform team pointed at an internal wiki last quarter.

So read the incidents by what got changed. Four disclosures, three vendors, one pattern that appears in none of the writeups.

Three vendors patched three different exits and left the same entry open

IncidentWhere the instruction enteredHow the data leftWhat the vendor changed
EchoLeak (CVE-2025-32711, CVSS 9.3)A crafted email, read by Microsoft 365 Copilot during ordinary retrieval, with no user interactionAttacker-supplied markdown that Copilot rendered, after clearing Microsoft’s own cross-prompt-injection classifier and link redactionServer-side screening and rendering behavior, with no customer action required
ForcedLeak (CVSS 9.4)The 42,000-character Description field of a Salesforce Web-to-Lead form, processed later when an employee asked Agentforce about the leadAn image URL pointing at a domain still sitting on the CSP allowlist, which had expired and cost about five dollars to buy backRe-secured the domain and enforced Trusted URL allowlisting on 8 September 2025
CamoLeak (CVE-2025-59145, CVSS 9.6)An invisible markdown comment in a pull request description, pulled into Copilot Chat as repository contextGitHub’s own Camo image proxy, driven by a pre-generated dictionary of signed URLs at one request per characterDisabled image rendering in Copilot Chat on 14 August 2025

Read the fourth column on its own. Microsoft hardened screening and rendering. Salesforce bought back a domain and tightened an allowlist. GitHub turned off images.

Three research teams working independently, three unrelated products, three fixes to the same half of the attack. Not one stopped an agent from following instructions it found inside content. Copilot still reads pull request comments. Agentforce still processes lead descriptions. The instruction still lands, and the door it walked the data out of is shut.

That gives every documented example the same two parts. The injection surface is content the agent was built to read, and it is load-bearing for the product: an inbox, a CRM record, a pull request. The exfiltration channel is the path the data took out, and it is always something the platform had already decided to trust.

Vendors patch the channel because the channel is patchable. The surface is the product, and OWASP has ranked this class first since the list existed for exactly that reason.

The payloads are ingenious because the exit was the attacker’s constraint

Look at how much work the exfiltration took.

A dictionary of pre-signed proxy URLs, fired one HTTP request per character of stolen data. A dead domain rescued off an allowlist for the price of a coffee. Those are not the moves of an attacker with options. They are the moves of an attacker working against a browser: Copilot Chat, Agentforce and Microsoft 365 Copilot could render text and fetch images, so the research went where the capability was, and the capability was a picture.

Now inventory the agent your team shipped. It holds a database client because querying is its job, an outbound HTTP tool because calling APIs is its job, an object-store credential, a service account token mounted at a path it can read, and a network policy written by someone reasonably worried about breaking it.

The entry is identical. The exit is unrecognizable.

So the published payloads are the wrong calibration target, and the place this bites is procurement. A classifier benchmarked on a corpus assembled from disclosed attacks is being scored against the constraint those researchers worked under. When a vendor quotes a detection rate, ask which evaluation produced the number, because a static benchmark and an adaptive attacker return figures that differ by an order of magnitude. Nothing in your cluster will ever generate a Camo URL or a resurrected CSP domain. Your agent never needs to smuggle anything past a rendering layer. It has a socket.

Reducing the arrival rate is still worth doing, and every payload stopped at the door is an incident nobody investigates.

The good news is that the asymmetry runs both ways. An attacker with a socket does not have to be clever, and an attacker who does not have to be clever leaves a blunt trace in execution. Skipping the encoding trick costs the attacker its stealth. The tool call happens in the open.

The one incident shaped like your cluster needed no exit at all

CVE-2025-53773 exfiltrated nothing.

The instruction arrived the way all the others did, hidden in a README, a source file or a GitHub issue that Copilot’s agent mode read while working. What happened next was a write to disk. The agent added “chat.tools.autoApprove”: true to .vscode/settings.json, which disables confirmation prompts, which hands it shell command execution on the developer’s machine.

There is no fourth-column trick there because there was nothing to smuggle. The agent could write files and run commands, so it did both.

Watch what that forced Microsoft to do. With no channel available to close, the August 2025 patch went to the other side of the problem and required human approval before the agent could change security-relevant configuration. That is the exception that explains the rule: vendors reach for the channel first because the channel is cheap, and they touch the agent’s capability only when the channel is not there to take.

Confirmation gating is also the capability control that scales worst. Approval on a coding agent’s config writes costs a developer three seconds. Approval on a remediation agent’s every action costs you the agent. The versions that hold at scale are structural rather than interactive, governing where data may travel instead of asking a human each time, and what they buy and what they miss is a question these incidents do not answer.

That is the incident that looks like production. An agent with filesystem access, tool access and the ability to rewrite its own configuration is a different animal from a chat assistant with an image renderer. It is the shape of a coding agent in a remote development environment, and the shape of most agents running on a cluster you own.

The volume side has caught up. Scanning two to three billion crawled pages a month, Google reported a 32% relative increase in the malicious category between November 2025 and February 2026, and Forcepoint’s X-Labs researchers flagged live payloads on patterns as plain as “Ignore previous instructions.”

None of it was aimed at anyone in particular. Targeting has become optional. An agent that browses or retrieves reads this material as a condition of the open web, and the only variable left is what it can do once it has.

Every step in every incident was authorized, which is what makes it coercion

Run the checks and watch them all come back clean.

In CamoLeak, Copilot ran with the requesting user’s permissions, read files that user was entitled to read, and made outbound requests through signed URLs that satisfied GitHub’s own Content Security Policy. In ForcedLeak, Agentforce queried CRM records it was provisioned to query and sent them to a domain on the allowlist. In EchoLeak, the email arrived through a mail flow doing its job and the content cleared Microsoft’s own injection classifier.

Identity valid. Permission valid. Destination approved. Content screened.

This is coercion: a trusted input redirecting an agent’s authorized capability toward someone else’s goal. No individual step is the attack. The sequence is the attack, and a control that evaluates steps one at a time will never assemble it. That convergence is why the entry path stops carrying information once the instruction is inside the context window.

That rules out most of the stack. RBAC returns valid. IAM returns valid. Network policy returns valid. A content classifier that already passed the payload does not get a second look at it, which is the residual every team is quietly carrying whether or not they have priced it. We have previously worked through how that residual gets detected once the payload is already inside a production agent.

Be precise about what that means here. A kernel-level sensor in your cluster would not have caught any of these three: CamoLeak’s exfiltration ran in the victim’s browser, and EchoLeak and ForcedLeak executed inside SaaS platforms nobody outside Microsoft and Salesforce can instrument. All three had a vendor security team and an engineer who could ship the fix. Your agents have neither, which is why the control has to sit somewhere you own.

What survives in that position is smaller and much harder to fake. The agent stops behaving like itself.

Measuring that needs a definition of normal belonging to one specific agent, derived from what it does rather than what its manifest permits. ARMO builds this as Application Profile DNA (APD™), a per-agent behavioral baseline assembled by one kernel-level eBPF sensor watching processes, files, syscalls, destinations and identity use. Declared permissions describe a ceiling, and the ceiling is the space coercion operates inside.

Enforcement runs off the same signal. In Audit, deviations get recorded and nothing is blocked, which is how a policy earns its way onto production traffic before it interrupts any. In Enforce, deviation stops, along the progression from audit to per-agent enforcement. Credential swapping closes the loop from the other side: the agent holds only dummy keys, so a coerced reach for a real credential returns something that does not work.

Run your own agents through the same split before you buy another filter

The exercise is two columns and an afternoon.

In the left column, for each agent, list every source of content it reads that somebody outside your organization can write into. There are five such surfaces in a production deployment, each with a different owner, and the one teams miss is tool and MCP responses, which get marked trusted because the agent chose to make the call.

In the right column, list every path data can take out. Not the paths you designed. Every tool it can invoke, every credential it holds, every destination its network policy permits, every store it can write to that something else later reads. The agent’s own response counts, which is the correction EchoLeak forces on anyone who filed their summarizers under harmless: a read-only assistant still has an output channel, and an output channel carried the data in the highest-profile case on the list.

Then score the right column by whether you could actually close each exit. This is where your situation stops resembling the writeups. Salesforce deleted a dead domain from an allowlist without touching anything customers use. GitHub gave up a real feature and could afford to, because rendering images was never what Copilot Chat was for. Your remediation agent’s write access is the reason it exists, and a support agent that cannot query the customer record is a dashboard.

Most of your exits stay open. Rank what to instrument by the width of that column, among the agents with anything in the left column at all. An agent that reads nothing an outsider can write cannot be injected and is not in this exercise. Among the rest, the instinct is to start with whichever handles the most hostile content. Start instead with the one holding the most ways out, because that is where an injection becomes an incident. A public summarizer reading a thousand hostile documents a day, with an output channel and nothing else, produces wrong answers and the occasional leaked context. A nightly reconciliation agent nobody talks to, parsing vendor invoices while holding a database credential and an egress route, produces a breach.

Read the columns together and you have the two axes that set a control budget: exposure to untrusted input on the left, authority to change state on the right. Agents sort into three classes on those axes, and the class decides what each one earns. The worksheet produces the inputs; the classification spends them.

Four dimensions carry the signal on whatever stays open: which targets the agent actually reaches against the much larger set it is permitted to reach, which orderings of tool calls it has executed before, which credentials it exercises rather than merely holds, and where its traffic genuinely goes.

The vendors in these examples could close their exits because their exits were incidental. Yours are the product. That leaves one honest place to put the control, at the point where the agent stops behaving like itself.

See how ARMO’s runtime security for AI workloads scores a coerced agent against its own baseline and contains it before the sequence finishes.

Frequently Asked Questions

Are the examples in this article still exploitable? The specific channels are closed. Microsoft, Salesforce and GitHub each shipped a fix, and the exfiltration paths described in the disclosures no longer work as published. The injection class those channels served is open, because none of the fixes changed whether a model follows instructions it finds in retrieved content. Treat the CVEs as closed and the underlying risk as standing.

How would I know if one of my own agents has already been coerced? Retro-hunting works better on the exit than the entry. Pull the historical tool-invocation record, egress destinations and credential use per agent, then look for targets and orderings appearing only once or twice across a long window. A pod-level or namespace-level log cannot tell you which agent did what, so if the telemetry was never attributed to a workload identity, the honest answer is that you do not know yet.

Does an AI gateway or content filter stop indirect prompt injection? It reduces the arrival rate, which is worth paying for. It cannot be the only control, because classifying adversarial prose is probabilistic and every published defense of that kind has broken under an adaptive attacker. EchoLeak cleared Microsoft’s own cross-prompt-injection classifier before anything else happened. Staff the filter for volume and staff a separate control for what gets through.

None of these incidents happened to us. Does that mean anything? Less than it feels like. Every case here was found on a product with a bug bounty, a disclosure process and researchers working it full time, which describes the discovery conditions rather than the population of vulnerable agents. Self-hosted agents have none of that machinery pointed at them, so an absence of findings is mostly an absence of anyone looking. Provenance across the five ingestion surfaces is the work that lets you answer this from your own telemetry instead.

Our agents run on a managed AI platform. Does that change anything? It changes who owns the left column and not who owns the consequences. The vendor screens content and patches its own rendering and egress paths, which is the half these incidents show getting fixed. The tools you registered, the credentials you provisioned and the systems you connected are the right column, and they are yours. A managed platform narrows the exits it controls and does nothing about the ones you added.

Close

Your Cloud Security Advantage Starts Here

Webinars
Data Sheets
Surveys and more
Group 1410190284
Ben Hirschberg CTO & Co-Founder
Rotem_sec_exp_200
Rotem Refael VP R&D
Group 1410191140
Amit Schendel Security researcher
slack_logos Continue to Slack

Get the information you need directly from our experts!

new-messageContinue as a guest