In the prompt injection breaches of 2025 and 2026, no attacker stole a password or token: an AI assistant or agent that already held legitimate access read poisoned content and carried company data out on the attacker's behalf. This guide takes three cases from the NHI Mgmt Group breach database, EchoLeak in Microsoft 365 Copilot, ForcedLeak in Salesforce Agentforce and SalesBleed, the 2026 follow-up against the same platform, and draws out the pattern they share. It then sets out the controls and steps that break that pattern, with the identity and access decisions that matter most. It is written for security architects, SaaS platform owners and IAM teams who run or are about to switch on AI assistants and agents. For the general mechanics of the attack class, read the Prompt Injection Guide first; this page is about what the incidents teach and what to change.
Key takeaways
- The agent's own access is the weapon. In all three cases the assistant acted with delegated or service access it already held, so the data at risk was exactly its retrieval and query scope.
- Anyone who can write into the agent's context can steer it. An inbound email, a public Web-to-Lead form and a lead record were enough; the attacker never logged in to the victim tenant.
- The exfiltration channel is usually rendering, not a tool call. Image loading, link previews, allowlisted domains and DNS lookups carried the data out, which is why output controls matter as much as input controls.
- Allowlists decay. ForcedLeak worked because an allowlisted domain had expired and could be bought; SalesBleed bypassed the Trusted URLs fix by exploiting URL parsing differences.
- Classifiers are a layer, not the control. EchoLeak bypassed a prompt injection classifier; the controls that hold are scope, separation of untrusted input from sensitive data, and egress limits.
What the breach data shows
The State of NHI & AI Agent Breach Report 2026 counts 64 breaches involving AI agents, LLM platforms, prompt injection or agent misbehaviour, out of 200+ analysed. Prompt injection was the attack route in 9 of them, and AI-related breaches went from 7 of 38 in 2024 to 19 of 63 in 2025 and 33 of 53 in 2026 so far. The report groups EchoLeak, ForcedLeak and SalesBleed under "agents hijacked by what they read", where poisoned content steers an agent that already holds valid access and no key is stolen. Its control mapping puts AI agent misbehaviour and prompt injection (20 breaches together) under Preventive Controls and Detection and Response: tool allow-lists, approval for risky actions, a tested kill switch, no standing production access, and treating agent input as untrusted. (Source: NHI Mgmt Group, The State of NHI & AI Agent Breach Report 2026 (October 2026).)
All three cases below were responsibly disclosed research, fixed by the vendor before or at disclosure, with no reported exploitation. That does not make them theoretical: each worked against production platforms with default or common configurations, and the same three ingredients exist in many in-house agents.
The three cases at a glance
| Case | Entry point | Identity doing the work | Exit channel | Control that failed |
|---|---|---|---|---|
| EchoLeak (CVE-2025-32711, disclosed 11 June 2025, Aim Labs) | A crafted email that Copilot later retrieved as context for an ordinary question | Copilot acting with the signed-in user's delegated access to mail, files, chats | Rendered output reaching a domain trusted by the Content Security Policy | Prompt injection classifier, link and image redaction, CSP trust of certain Microsoft domains |
| ForcedLeak (CVSS 9.4, disclosed 25 September 2025, Noma Labs) | Free text submitted through a public Web-to-Lead form | The Agentforce agent's own CRM access | An outbound request at render time to a CSP-allowlisted domain that had expired | Stale allowlist entry; no separation of untrusted lead text from CRM queries |
| SalesBleed (disclosed 24 September 2026, Zenity Labs) | A poisoned Web-to-Lead record, processed when an employee asked about leads | The default General CRM subagent, able to read both Leads and Accounts; a Slack reply action posting as the agent | Automatic image loading, Slack link unfurling, data encoded in DNS hostnames | Trusted URLs redaction applied after generation, with URL parsing that differed from the renderer |
Two further cases in the database follow the same shape with different tools. In the Gemini calendar prompt injection (disclosed 19 January 2026, Miggo Security), a calendar invite steered Gemini into writing private meeting summaries into a new event the attacker could read. In Sentry MCP agentjacking (June 2026, Tenet Security), a fake error event posted with a public Sentry DSN reached coding agents as trusted MCP tool output and put the developer's credentials within reach.
The shared pattern: three ingredients in one place
Zenity's summary of SalesBleed is the most useful lens: an agent that reads external records, renders links and holds data access has the three ingredients sitting in the same place. Read the cases against that and the lesson is architectural.
- Untrusted input: email from anyone (EchoLeak), unauthenticated web forms (ForcedLeak, SalesBleed), calendar invites (Gemini), error events written with a public key (Sentry). None of these sources authenticates the author, yet the agent treated their text as business data and, in effect, as instructions.
- Sensitive access: delegated user scope across Microsoft 365, or a CRM agent able to query beyond the object it was asked about. The blast radius equalled the agent's access, not the attacker's.
- An outbound path: a renderer that fetches images, a chat platform that unfurls links, a domain on an allowlist, a DNS lookup. In SalesBleed the data rode in the hostname, so HTTP egress filtering alone would not have stopped it.
Remove any one ingredient for a given session and the theft fails. That is a more reliable design goal than trying to detect every malicious instruction, because, as the Gemini case showed, the payload can read as an ordinary natural-language request.
Controls that break the pattern
| Ingredient | Control | What it would have changed |
|---|---|---|
| Untrusted input | Tag content by source (internal, authenticated partner, anonymous public) and keep anonymous-source records out of agent context by default, or route them to a reader agent with no data access | ForcedLeak and SalesBleed leads would reach an agent that could not query Accounts |
| Untrusted input | Treat MCP and tool output as untrusted data, not as instructions; never let tool output trigger shell, install or send actions without approval | Sentry fake "Resolution" text could not lead to command execution |
| Sensitive access | Scope each agent or subagent to the objects and fields its task needs; split read-external and read-sensitive into different identities | SalesBleed's General CRM subagent would lack Account read |
| Sensitive access | Reduce assistant retrieval scope with sensitivity labels and fix oversharing in SharePoint and OneDrive before broad assistant rollout | Narrows what an EchoLeak-style injection can reach |
| Outbound path | Disable automatic external image loading and link unfurling for agent output; allow only named destinations that you own | Removes the render-time channels used in all three cases |
| Outbound path | Review CSP entries, trusted URL lists, redirect URIs and webhooks for expired or unowned domains on a schedule | The ForcedLeak domain would have been removed before it lapsed |
| Outbound path | Monitor and restrict DNS resolution from agent runtimes; alert on long or high-entropy subdomains | Detects the SalesBleed DNS channel |
| Any write action | Require user confirmation and attribution for actions that move data: sending messages, creating events, posting to Slack, updating records | Blocks the SalesBleed Slack phishing and the Gemini calendar write |
For the egress side in depth, see the Agent Egress Control and Network Isolation Guide. For approval design, see the Human-in-the-Loop for AI Agents Guide.
Where identity fits
Each of these assistants is a non-human identity with an access profile, whether the platform calls it a copilot, an agent or a subagent. The identity questions are the ones that decide the outcome:
- Whose access does it use? Delegated (acts as the user, as in EchoLeak and Gemini) or its own service identity (as in Agentforce). Delegated agents inherit every overshare the user has; service-identity agents need their own least-privilege role.
- Who owns it? Every agent needs a named owner who approves its data scope, tools and input sources, and who is paged when it misbehaves.
- Who is it attributed to? Messages and record changes made by an agent must show both the agent and the human who triggered it. SalesBleed's Slack action posted as the agent with no attribution, which is what made anonymous phishing possible.
- What else is in its environment? Coding agents inherit the developer's AWS keys, GitHub tokens and SSH agent. Keep long-lived secrets out of agent environments and use short-lived, narrowly scoped credentials, as the AI Agent Credential Lifecycle and Rotation Guide describes.
See the Agent Identity and Access Guide for the governance model.
Implementing the controls in phases
- Inventory (week 1 to 2): list every AI assistant and agent, its identity type (delegated or service), owner, data scope, tools, input sources and output surfaces (chat, Slack, email, web). Flag any agent where anonymous input, sensitive access and external rendering coexist.
- Close render channels (week 2 to 3): turn off external image loading and link unfurling for agent output where the platform allows it; enforce the vendor's trusted URL feature (for Agentforce, Trusted URLs enforcement); review every allowlisted domain for ownership and expiry. Test in a sandbox org or pilot group first, and keep the previous configuration exported so you can roll back if a business flow breaks.
- Split scope (week 3 to 6): separate agents that read public-source records from agents with sensitive data access; remove object and field permissions not needed for the task; apply sensitivity labels and fix oversharing before widening assistant rollout.
- Gate actions (week 4 to 6): require confirmation and attribution for sends, posts, shares, event creation and record updates; require approval for any command execution that originates from tool output.
- Clean up stored poison (once, then on schedule): audit existing Web-to-Lead and other public-form records for instruction-like text in free-text fields, because a poisoned record stays in place and can trigger again.
- Test (quarterly): run benign indirect injection tests against each flagged agent, using canary data and a domain you control, and confirm that no channel carries the canary out. The AI Agent Security Testing Checklist covers test design.
Detection and measurement
Log what each agent retrieved, the tool it used, the user it acted for and the input that triggered the action, so an incident can be traced back to the poisoned record. Useful signals: agent output containing external URLs or image references; DNS queries from agent runtimes to unfamiliar domains or with long encoded labels; agent queries that span objects unrelated to the user's request; agent-authored messages to channels or people the triggering user does not usually contact.
| Metric | Target |
|---|---|
| Agents with an owner, data scope and input sources recorded | 100% |
| Agents combining anonymous input, sensitive access and external rendering | 0, or each one with a documented exception |
| Allowlisted or trusted domains with verified ownership and expiry date | 100%, reviewed at least quarterly |
| Data-moving agent actions that require confirmation and carry user attribution | 100% |
| Quarterly canary injection tests where data left the tenant | 0 |
If an injection is suspected, follow the Prompt Injection Incident Response Playbook and, for scoping what left, Investigating Agent-Initiated Data Exfiltration.
Framework mapping
| Framework | Item | Relevance to these cases |
|---|---|---|
| OWASP Top 10 for LLM Applications 2025 | LLM01:2025 Prompt Injection (indirect) | The entry technique in all three cases; mitigations include least privilege, human approval for high-risk actions and segregating external content |
| OWASP Top 10 for LLM Applications 2025 | LLM06:2025 Excessive Agency | Over-broad tool scope and permissions, as with the SalesBleed subagent and Slack action |
| MITRE ATLAS | AML.T0051.001 LLM Prompt Injection: Indirect | Instructions delivered through retrieved email, leads and invites |
| MITRE ATLAS | AML.T0057 LLM Data Leakage; AML.T0086 Exfiltration via AI Agent Tool Invocation | Data disclosed through output and through agent actions such as the Slack reply or calendar write |
| NIST SP 800-53 Rev. 5 | AC-6 Least Privilege; SI-10 Information Input Validation; SC-7 Boundary Protection; AU-12 Audit Record Generation | Scope, untrusted input handling, egress limits and action logging |
Common failure patterns
- Relying on a classifier: EchoLeak bypassed Microsoft's prompt injection classifier and the Gemini payload read as a normal request. Detection helps, but scope and egress decide the outcome.
- Trusting an allowlist nobody owns: ForcedLeak used a domain that was still trusted after it had expired. Allowlists need owners and expiry checks.
- Redacting after the fact: SalesBleed showed that a redaction layer which parses URLs differently from the renderer can be bypassed. Prefer not rendering external content at all.
- Default subagent scope: the default General CRM subagent in SalesBleed could read Leads and Accounts together. Review defaults before go-live.
- Agent actions without attribution: an agent that posts as itself, with no link to the triggering user, turns a trusted identity into an anonymous messenger.
- Treating a fix as closure: ForcedLeak was fixed in 2025 and SalesBleed bypassed the fix in 2026. Re-test after each vendor change.
Practitioner checklist
- Inventory every AI assistant and agent with owner, identity type, data scope, tools, input sources and output surfaces.
- Flag and fix any agent that combines anonymous input, sensitive data access and external rendering.
- Disable external image loading and link unfurling for agent output, and enforce the platform's trusted URL controls.
- Review CSP entries, trusted URLs, redirect URIs and webhooks for expired or unowned domains every quarter.
- Scope each agent and subagent to the objects and fields its task needs; split public-input readers from sensitive-data agents.
- Require confirmation and user attribution for agent sends, posts, shares, event creation and record changes.
- Treat MCP and tool output as untrusted; require approval before any command it suggests runs.
- Audit stored public-form records for instruction-like text, and monitor DNS from agent runtimes.
- Run quarterly canary injection tests, and re-test after every vendor fix or platform update.
Standards and references
- NHI Mgmt Group: The State of NHI & AI Agent Breach Report 2026 (October 2026)
- OWASP: LLM01:2025 Prompt Injection
- OWASP: LLM06:2025 Excessive Agency
- MITRE ATLAS: LLM Prompt Injection
- NIST: SP 800-53 Rev. 5
- Noma Security: ForcedLeak, agent risks exposed in Salesforce Agentforce
- Zenity Labs: SalesBleed, 0-click data exfiltration in Agentforce
- arXiv: EchoLeak, The First Real-World Zero-Click Prompt Injection Exploit in a Production LLM System
Related NHI Mgmt Group resources: Prompt Injection Guide · OWASP LLM Top 10 LLM06 Excessive Agency Guide · Agent Threats and Attacks Guide · Agent Controls and Monitoring Guide