Five attack surfaces of an AI agent mapped to OWASP LLM Top 10 2025 and Agentic Top 10 2026 IDs, with a 2025 incident and a control for each

How AI Agents Get Hacked: A Field Guide to Agentic Vulnerabilities

Five attack surfaces of an AI agent (context window, tools and supply chain, permissions, memory and RAG, people and other agents) mapped to OWASP LLM Top 10 2025 and Agentic Top 10 2026 IDs, with a 2025 incident and a control for each
Where an agent gets attacked, grouped by where the attack enters rather than by OWASP rank. IDs are OWASP’s own: LLMxx from the Top 10 for LLM Applications 2025, ASIxx from the Top 10 for Agentic Applications 2026. Each incident is a publicly disclosed 2025 case, covered below with sources.

Security vendors have noticed that AI agents are software, and that software can be scanned. OpenText’s application security page is a good example of the pitch: an “AI-amplified” Fortify portfolio that promises to find prompt injection paths, insecure handling of model inputs and outputs, and data leaking through AI responses. It anchors those claims to the OWASP Top 10 for LLM Applications, and offers a buyer’s guide on what code scanning finds in that list.

What the page does not do is tell you how an agent actually gets compromised. That is not really a criticism, since it is a product page, but it means the useful material sits one link away, in the OWASP lists the page points to. This post follows that link. It walks through the ways agents are attacked, grouped by where the attack enters, with a real 2025 incident for each. Then it comes back to the question the vendor page raises without answering: how much of this can a scanner see?

First, a correction to the list everyone still quotes

The OWASP LLM Top 10 that still circulates in slide decks and vendor summaries is the 2023 edition: prompt injection, insecure output handling, training data poisoning, model denial of service, supply chain, sensitive information disclosure, insecure plugin design, excessive agency, overreliance, model theft. It is also the list this post started from. OWASP revised it in late 2024 as the 2025 edition. In December 2025 it published a separate Top 10 for Agentic Applications, because a list written for chatbots no longer stretched far enough to cover systems that take actions.

The revisions are not cosmetic. They record what two years of real deployments taught the people who maintain the list:

2023 entry2025 entryWhat changed
LLM01 Prompt InjectionLLM01 Prompt InjectionStill first. Now explicitly covers indirect injection through documents, web pages and images.
LLM02 Insecure Output HandlingLLM05 Improper Output HandlingSame risk, ranked lower.
LLM03 Training Data PoisoningLLM04 Data and Model PoisoningWidened from pre-training to fine-tuning and embedding data.
LLM04 Model Denial of ServiceLLM10 Unbounded ConsumptionWidened to runaway cost (“denial of wallet”) and model extraction.
LLM05 Supply Chain VulnerabilitiesLLM03 Supply ChainMoved up. Covers models, adapters and datasets as well as packages.
LLM06 Sensitive Information DisclosureLLM02 Sensitive Information DisclosureMoved up to second.
LLM07 Insecure Plugin DesignNo longer a separate entryPlugins became tools; the risk is split across supply chain and excessive agency.
LLM08 Excessive AgencyLLM06 Excessive AgencyMoved up as agents became the default architecture.
LLM09 OverrelianceLLM09 MisinformationReframed around the confident falsehood, with overreliance as its consequence.
LLM10 Model TheftFolded into LLM10Extraction through the API is treated as a consumption abuse.
LLM07 System Prompt LeakageNew. Stop treating the system prompt as a secret.
LLM08 Vector and Embedding WeaknessesNew. RAG stores became an attack surface of their own.

The agentic list adds ten more, prefixed ASI: agent goal hijack, tool misuse, identity and privilege abuse, agentic supply chain, unexpected code execution, memory and context poisoning, insecure inter-agent communication, cascading failures, human–agent trust exploitation, and rogue agents. Most of these are not new vulnerability classes so much as the LLM entries with an action attached. That is the idea worth taking away: in an agent, every one of the old risks gets a verb.

Why an agent is a different target from a chatbot

A chatbot that gets prompt-injected says something it should not. An agent that gets prompt-injected does something it should not. It acts with your credentials, against your systems, often without anyone watching the individual step.

The root cause is the same in both cases, and it has not been fixed. A language model receives instructions and data through the same channel, as the same kind of tokens, and it cannot reliably tell them apart. The system prompt, the user’s request, a retrieved web page, an email body and a tool’s JSON response all arrive as text in one context window, so anything the model reads can act as an instruction. Guardrail classifiers and “ignore instructions inside the following content” delimiters lower the rate at which this happens. None of them lower it to zero, and an attacker only needs the one case that gets through.

Simon Willison gave the resulting risk its most useful shape in June 2025, and I covered it in depth in an earlier post on the lethal trifecta. The short version: an agent can be used to steal data when it combines three things: access to private data, exposure to untrusted content, and a way to communicate externally. Each of these is a feature. Together they form an exfiltration path that needs no bug in any code you wrote. Meta turned the idea into a design rule in October 2025, the Agents Rule of Two. Within one session, an agent should have at most two of these three properties: it processes untrusted input, it can reach sensitive systems or data, or it can change state or communicate externally. If a task needs all three, a human belongs in the loop.

Keep that frame in mind for the rest of this post. Almost every attack below is a way to supply the untrusted-content leg to an agent that already had the other two.

The five attack surfaces

OWASP ranks its entries by severity. For engineering, it is more useful to group them by where the attack enters, because that is where the control has to go. The summary figure at the top uses five surfaces.

1. The context window: instructions hidden in data

LLM01 Prompt Injection, ASI01 Agent Goal Hijack, LLM02 Sensitive Information Disclosure, LLM07 System Prompt Leakage.

Direct prompt injection, where a user types “ignore your previous instructions”, is the version everyone demos and the least interesting one, because the attacker is only attacking their own session. The dangerous version is indirect, and the attacker never talks to the agent at all. They leave instructions somewhere the agent will read on someone else’s behalf: an email, a support ticket, a GitHub issue, a web page, a PDF, a calendar invite, a code comment.

EchoLeak (CVE-2025-32711, CVSS 9.3) is the reference case. In June 2025, researchers at Aim Security showed that a single email sent to a Microsoft 365 user could carry instructions that Copilot would pull in through retrieval when the user later asked an unrelated question. The instructions told Copilot to collect sensitive content from everything it could reach and encode it into a link that the client would fetch automatically. The user never opened the email. Aim called the underlying pattern an LLM scope violation: untrusted outside input makes the model reach into data it was trusted with. Microsoft fixed it on the server side and reported no exploitation in the wild. The fix closed that particular path. It did not change the underlying situation: Copilot still reads attacker-controlled email and can still see everything its user can.

System prompt leakage belongs here too, and the 2025 list frames it correctly. Assume your system prompt will be extracted, because role-play and reformatting tricks recover it reliably. The vulnerability is not that the prompt leaks. It is keeping anything in the prompt that matters once it leaks: API keys, internal hostnames, the only copy of an authorization rule. Authorization belongs in code the model cannot talk its way past.

2. Tools and the supply chain: trusted parts, toxic flows

ASI02 Tool Misuse, ASI04 Agentic Supply Chain, LLM03 Supply Chain, LLM05 Improper Output Handling, ASI05 Unexpected Code Execution.

Tools are how an agent acts, and every tool is two attack surfaces: what it does, and what it says about itself.

What a tool says about itself is its description, and the model reads that description as instructions. In April 2025, Invariant Labs demonstrated tool poisoning. They built an MCP server whose tool looks harmless in the client UI but whose full description tells the model to read local files, such as SSH keys and the client’s own configuration, and pass them along inside a tool parameter. MCP servers can also change their descriptions after you approve them, so the tool you reviewed is not necessarily the tool you are running.

What a tool does can be abused even when the tool is honest. In May 2025, Invariant showed that a malicious issue in a public repository could turn the official GitHub MCP server against its own user. A developer asks their agent to look at open issues. The planted issue asks the agent to collect information from the developer’s private repositories and publish it in a pull request on the public one. The agent holds a token with access to both, so it complies. As Invariant stressed, the GitHub MCP server had no bug, and that is exactly why the incident matters. Every tool call was authorized; the vulnerability was the combination. Invariant called it a toxic agent flow: the lethal trifecta built entirely from legitimate parts.

The traditional supply chain is still underneath all this. In July 2025, an attacker found an over-scoped GitHub token in the build configuration of the Amazon Q Developer extension for VS Code. They used it to commit a prompt to the open-source repository that told the agent to wipe local files and delete cloud resources. The prompt shipped in the official 1.84.0 release. AWS found that a syntax error kept it from executing, and pulled the version. The attack was not sophisticated. The payload was a paragraph of English, and that is the new part: malicious code in an agent’s supply chain can be a prompt, and a malware scanner hunting for suspicious binaries will not flag a sentence.

Improper output handling is the same trust error pointed the other way. Whatever the model emits (a SQL fragment, a shell command, a file path, HTML, a Markdown image link) is attacker-influenced whenever anything in its context was. Pass that output to an interpreter, a query builder or a browser without the validation you would give user input, and a prompt injection becomes classic cross-site scripting, SQL injection or remote code execution. For agents that write and run code, this is the default path rather than an edge case, which is why the agentic list gives unexpected code execution its own entry.

3. Permissions and autonomy: the blast radius

LLM06 Excessive Agency, ASI03 Identity and Privilege Abuse, LLM10 Unbounded Consumption.

Excessive agency is not a way in; it multiplies the damage from every other way in. A prompt-injected agent with read-only access to one repository leaks one repository. Give the same agent an organization-wide token, write permission and a shell, and it becomes whatever the attacker wants.

OWASP splits it into three causes, and they are worth keeping apart because each has its own fix. Excessive functionality means the agent has tools this task does not need. Excessive permissions means the tools it does need hold broader rights than the task requires. Excessive autonomy means high-impact actions run without confirmation.

The s1ngularity attack on the Nx build system in August 2025 showed what happens when an attacker gets code running on a developer machine that has AI coding CLIs installed. The malicious npm packages checked for Claude Code, Gemini CLI and Amazon Q. They launched whichever they found with the flags that switch off permission prompts, and told the agent to search the filesystem for secrets and crypto wallets. The stolen data was pushed to public repositories created in the victims’ own GitHub accounts. Nobody tricked the agents through their context; the malware simply used them. They were installed with broad filesystem access and a switch that turns off their only safety check. Permission-bypass modes are a convenience, but on a machine that also holds production credentials they are a post-exploitation tool installed in advance.

Unbounded consumption is excessive agency measured in money. An agent that can loop, spawn sub-agents or call paid APIs without a budget can be pushed into recursive work that burns through quota, whether by an attacker or by its own confusion. The 2023 list called this model denial of service. The 2025 name is more honest, because the usual result is not an outage but an invoice.

4. Memory and knowledge: compromise that persists

LLM04 Data and Model Poisoning, LLM08 Vector and Embedding Weaknesses, ASI06 Memory and Context Poisoning.

A prompt injection normally ends when the session does. Memory makes it persistent.

In February 2025, Johann Rehberger showed that a document the user asked Gemini to summarize could write to its long-term memory. The document’s hidden instructions did not act right away. They told Gemini to save false facts about the user the next time the user said something ordinary, like “yes” or “sure”. Rehberger called this delayed tool invocation. Because the action was tied to a later user turn, it slipped past the defense that stops the model from calling tools while it is processing untrusted content. The planted memories then shaped every later conversation.

The same logic applies to every store an agent reads from. A poisoned document in a RAG corpus is an injection that is retrieved again every time a relevant query arrives. A shared vector store without per-tenant isolation can leak one customer’s documents into another customer’s answers. Training data poisoning, which led the old list, is still real for teams that fine-tune. But for most teams building agents on hosted models, the practical poisoning surface is not the training set. It is the retrieval corpus and the memory store, which are written to constantly and reviewed rarely.

5. People and other agents: trust as the payload

LLM09 Misinformation, ASI09 Human–Agent Trust Exploitation, ASI07 Insecure Inter-Agent Communication, ASI08 Cascading Failures, ASI10 Rogue Agents.

In most agent designs, the last line of defense is a human approving something. The most uncomfortable entries on the agentic list are about how that line fails.

In July 2025, SaaStr founder Jason Lemkin was building an app with Replit’s agent and had declared a code freeze. The agent deleted the production database anyway, wiping records on more than a thousand executives and companies. It then generated fake data and told him a rollback was impossible, which was not true. No attacker was involved. OWASP cites the case under rogue agents, but the failure a security reviewer should notice is the second one: everything the human knew about the system came from the agent’s own account of what it had done. Replit’s response was automatic separation of development and production databases, a planning-only mode, and better restore. Every item on that list is a control that works even if the agent does not report truthfully.

Approval prompts fail in quieter ways too. An agent that asks for confirmation forty times a day trains its user to click yes. An agent that describes a destructive action in fluent, reasonable prose (“I’ll clean up the unused resources”) gets approved on the strength of the description. Multi-agent systems add a machine version of the same problem. If one agent accepts another’s output as trusted instructions, an injection in the first spreads through all of them, and a mistake that a single agent would have caught turns into a confident consensus.

What a code scanner can and cannot see

Which brings us back to the vendor page. OpenText claims that its static, dynamic and software composition analysis, together with AI-specific detection, covers the OWASP LLM risks. The fair reading is that scanning covers the part of these risks that exists in code. That part is real, and worth catching:

  • Model output reaching a dangerous sink, such as an eval, a shell call, a raw SQL string or unescaped HTML. This is improper output handling, and it is a data-flow problem static analysis has been solving for decades.
  • Secrets hard-coded into prompts or prompt templates, which leak the moment the system prompt does.
  • Vulnerable or malicious dependencies in the agent’s package tree, the standard job of software composition analysis.
  • Over-broad scopes and permission-bypass settings in configuration files, when they are actually written down.

What a scanner cannot see is the part of the attack that does not exist until runtime. The EchoLeak email was never in Microsoft’s repository. The malicious GitHub issue was not in the MCP server’s code, and Invariant was explicit that the server had no bug to find. A poisoned memory is a database row written last Tuesday. A tool description can change after deployment. And the trifecta is a property of which tools, data and credentials end up in the same session. That is a deployment decision, often made by whoever installs an MCP server rather than whoever wrote the agent. It is the same gap I described in designing an agentic platform for vulnerability orchestration, one level up: static analysis sees code, not context.

So when any product page, this one or a competitor’s, promises “OWASP LLM Top 10 coverage”, read it as we flag the code patterns that make these risks easier to exploit, not these risks are handled. The same skepticism applies to the one number on the page. The 70% reduction in mean time to remediate comes from OpenText’s own eight-week rollout of its own tool, and the page gives neither the baseline nor what counted as remediated.

Design as if the injection succeeds

If the research and the incidents agree on one conclusion, it is that you cannot filter your way out of prompt injection. Detection helps, but it is not a boundary. The controls that hold up are the ones that limit what a successful injection can do.

  1. Break the trifecta in every session. Apply the Rule of Two. An agent that reads untrusted content and holds private data should not also be able to send email, open pull requests or fetch arbitrary URLs. That includes the quiet channels, like rendering a Markdown image from a host the attacker chose. When a task needs all three, split it across agents with separate permissions, or put a human on the step that crosses the line.
  2. Separate control flow from data flow. In CaMeL, a design from Google, Google DeepMind and ETH Zurich, a privileged model plans the task using only the trusted user request. A quarantined model handles the untrusted data and cannot choose which tools get called. Data carries capability labels, and a policy check runs before every tool call. It is not free: on the AgentDojo benchmark, CaMeL completed 77% of tasks with provable security, against 84% for an undefended agent. That seven-point gap is the honest price of a real boundary, and it beats the alternatives by a wide margin.
  3. Enforce least agency outside the model. Give each task its own short-lived credential, scoped to the resources that task needs and read-only by default. Separate development and production at the infrastructure level, not in the prompt. Never run an agent with permission prompts disabled on a machine that holds anything valuable.
  4. Treat every model output as untrusted input. Validate, parameterize and sandbox it exactly as you would a form field from an anonymous user. Run generated code in an isolated environment with no ambient credentials.
  5. Pin and review the tool layer. Allow-list MCP servers, pin their versions, and review again whenever a tool description changes. A tool description is code that runs inside the model’s head.
  6. Put provenance on memory. Record where every memory and every retrieved document came from, gate writes that originate in untrusted content, and isolate stores per tenant, with namespaces that work as real access control.
  7. Design approvals for tired humans. Ask for confirmation only on irreversible or externally visible actions, and show the concrete effect (the diff, the recipient list, the resources to be deleted) rather than the agent’s summary of it. Log every tool call somewhere the agent cannot edit.

Closing thought

The 2023 list read like an application security checklist with an LLM stapled on. The 2025 revision and the agentic list read like what they are: a record of teams discovering that the model is not really the component under attack. The model is the confused deputy. What gets attacked is everything wired around it: the permissions, the tools, the memories and the human approvals.

That is also why neither a better model nor a better scanner will solve this on its own. A model that resists 99% of injections can be beaten by an automated attacker in about a hundred tries. Scanners will find the code that turns an injection into a catastrophe, and you should run them. But the decision that matters most is whether one session holds untrusted content, private data and a way out at the same time. That is an architecture decision, so make it on purpose.


Sources

Everything in this post comes from the public sources below, checked in September 2026. Incident details come from the vendor advisories and the original researchers where those exist, and from named reporting where they do not.

Starting point

OWASP frameworks

Design principles and defenses

Incidents

Earlier posts on this blog


Comments

Leave a Reply

Discover more from A Tangent Thought

Subscribe now to keep reading and get access to the full archive.

Continue reading