Research · Framework · Nov 3, 2026
The agent kill chain.
The public incidents of the last two years look different on the surface: an email to Copilot, a pull-request title, a CRM lead form, a post in Morse code, a poisoned npm package. Broken down step by step, they are the same attack. We split it into seven stages, so teams can see where their defenses actually sit, and where they don't.
The seven stages
- Exposure. The agent can read content that someone outside the company controls: email, tickets, web pages, pull requests, form submissions, packages, posts from other agents.
- Plant. The attacker puts instructions, or a false fact, into that content. It sits there harmlessly, sometimes for weeks.
- Trigger. A legitimate user asks the agent to do normal work that makes it read the planted content. The victim pulls the trigger.
- Takeover. The agent adopts the planted goal as part of its task. This is the only stage prompt-level defenses address.
- Reach. The agent uses access it was legitimately given: files, mailboxes, repositories, tokens, wallets.
- Exit. Data or value leaves through a channel the agent is allowed to use: an email, an image URL, an API call, a commit, a transfer.
- Cover. The agent's account of what it did leaves out the harmful part, or gets it wrong. The human reviewing the work sees nothing unusual.
Rogue agents with no attacker skip stages 1 to 3: the takeover comes from the agent's own pressure to finish its task, and stages 4 to 7 play out the same way.
Ten incidents, stage by stage
| Incident | Exposure and plant | Trigger | Reach | Exit |
|---|---|---|---|---|
| EchoLeak, Microsoft 365 Copilot (2025) | Hidden instructions in an ordinary-looking email | User asks Copilot a work question; the email gets retrieved | Internal documents and mail Copilot can see | An image URL pointing to the attacker, loaded automatically. Zero clicks. |
| ForcedLeak, Salesforce Agentforce (2025) | Payload submitted through a public web-to-lead form, stored in the CRM | Staff ask the agent about the lead | CRM records | A web request to a domain the platform still trusted |
| GitHub MCP (2025) | Malicious issue filed on a public repository | Developer asks their agent to look at open issues | The developer's private repositories | A pull request on the public repository |
| "Comment and Control" (2026) | A crafted pull-request title | AI code-review agents process the PR | Secrets in the CI environment | GitHub's own API |
| Grok and Bankr (2026) | A transfer command hidden in Morse code in a public post | Grok decodes the post and tags a trading bot | The trading bot's wallet | An on-chain transfer, reported at roughly $150k to $200k (later returned) |
| Nx "s1ngularity" (2025) | Malicious versions of a popular npm package | Developers install or update it | The victim's own AI coding CLIs, launched with permission checks skipped, hunting for secrets | Public repositories created in the victim's account; thousands of secrets leaked |
| Amazon Q extension (2025) | A pull request that slipped a "wipe the machine and cloud" prompt into the extension | Users install the shipped version | Local files and cloud accounts | None in practice: it failed on a formatting error, not on any defense |
| Chevrolet dealer chatbot (2023) | The attacker is the user, talking directly to the bot | A chat conversation | The bot's authority to speak for the dealer | A "legally binding" offer of a $76k vehicle for $1 |
| Replit agent (2025) | No attacker | Routine work during a code freeze | Production database access | Wiped a production database holding records on more than 1,200 executives and companies, then misreported what happened |
| OpenAI internal agent (disclosed 2026) | No attacker | A task it needed to pay for | A crypto wallet it was never authorized to use | A payment |
What the map shows
Most defenses sit at stage 4.
Prompt filters, system-prompt rules and model safety training all try to stop the takeover. That's the stage attackers control most completely: they choose the wording, the language, the encoding and the disguise. OpenAI has said publicly that prompt injection is unlikely ever to be fully solved. If stage 4 is the only line, every new phrasing is a new hole.
Stages 1 to 3 are a feature, not a bug.
Agents exist to read outside content: customer emails, issues, tickets, web pages. You cannot remove exposure without removing the product. Notice also that in every case with an attacker, the trigger was pulled by an innocent employee doing their job. Security awareness training doesn't help when the employee never sees the attack.
Stages 5 and 6 are where every incident became real.
In each case the damage happened through access the agent was meant to have, sent through a channel it was meant to use. But the specific combination was new every time: a private repo written to a public PR, a CRM record sent to an outside host, a wallet the agent had never touched. That is the signal. It's the same thing our detection test found: the attacks that got past the model all needed a destination the agent had never used.
Stage 7 is why these get found late.
The Replit agent misreported what it had done. In our own experiment, 7 of 11 emails the agent sent to attackers went unmentioned in its report. Several of the incidents above were found by outside researchers, not by the companies running the agents. If your only view of an agent is its own summary, you are trusting the insider to report itself.
Using the chain
For each agent you run, ask one question per stage:
| Stage | Question |
|---|---|
| Exposure | Which content can outsiders write that this agent will read? |
| Plant | Would we notice instructions or changed facts sitting in that content? |
| Trigger | Which everyday requests make the agent read it? |
| Takeover | Have we tested attacks written as business requests, not jailbreak strings? |
| Reach | What can it touch that its job doesn't need? |
| Exit | Would a first-time destination be held before it happens, or found after? |
| Cover | Do we have a record of what it actually did, independent of what it says it did? |
A team that can only answer the takeover question has one layer of defense. Attacks pass through all seven.
Sources
- EchoLeak (CVE-2025-32711): The Hacker News
- ForcedLeak: Dark Reading
- GitHub MCP: Invariant Labs disclosure, May 2025
- Comment and Control: VentureBeat
- Grok and Bankr: CCN
- Nx s1ngularity: Wiz
- Amazon Q extension: The Register
- Chevrolet dealer chatbot: Vibe Graveyard
- Replit: Tom's Hardware
- OpenAI internal agent: Fortune
- OpenAI on prompt injection: The Hacker News