The OWASP Top 10 for LLM Applications (2025) is the most useful shared vocabulary the field has for talking about what goes wrong in LLM and agentic systems. It is also, like every Top 10, a risk register — and a risk register is not a control set. "Prompt Injection" is a category, not an instruction. The gap between naming a risk and shipping a control is where most AI security work actually lives, and it is a gap that has to be closed in code, in the pipeline, and in architecture — not in a policy document.
This article does that translation. For each of the ten, we give the concrete controls a development or MLOps team builds, where in the stack they belong, and how you verify they work. It is written for the people who have to implement this — engineers, ML platform teams, and the security architects who interface with them — not for a slide at a board meeting.
Two framing points before the list.
The model is not the security boundary. Almost every control below lives around the model — in the application runtime, the retrieval layer, the tool-calling harness, the pipeline, the egress path. Treating the LLM as an untrusted component that you wrap in controls, rather than a thing you try to make trustworthy by prompting, is the single most important mental shift. Prompt engineering is a mitigation; it is never a control boundary.
Agentic systems raise the stakes on every item. The 2025 revision explicitly reflects the rise of agentic AI. The moment a model can call tools, browse, write to systems, or spend money, the blast radius of every risk below scales with the privilege you granted it. Where a control matters more for agents, we say so.
LLM01:2025 — Prompt Injection
The risk: attacker-controlled input alters the model's behaviour. Direct injection is in the user's own prompt; indirect injection is planted in content the model later retrieves (a web page, a document, an email, a code comment) and is the more dangerous variant because the user never sees it. We covered live indirect-injection payloads in a recent brief.
Controls engineers build:
- A data/instruction boundary in the runtime. Retrieved or third-party content must enter the context tagged as data to be reasoned over, never as instructions to be followed. This is an agent-runtime design decision (how you assemble the context window), not a prompt-wording trick.
- Least-privilege tool design. Injection only matters to the extent the model can act. Scope every tool the model can call to the minimum capability; require explicit, separately-authorised confirmation for any high-impact action (payment, deletion, outbound mail).
- Input/output mediation. Pattern-detect known injection markers ("ignore previous instructions",
[SYSTEM], instructionalaria-hiddentext) as signal — not as a primary defence, but as detection. - Egress control. Constrain and log outbound calls from the agent runtime; most published injection attacks require the agent to reach a third-party host to complete.
Where it lives: application runtime + tool-calling harness + network egress. How to verify: red-team with adversarial documents in the retrieval corpus (see the red-teaming section); assert that injected instructions in retrieved content cannot trigger a privileged tool call without human confirmation.
LLM02:2025 — Sensitive Information Disclosure
The risk: the system reveals data it should not — PII, secrets, proprietary data, or another user's context — through model output.
Controls engineers build:
- Scope what enters the context. The strongest control is upstream: don't put secrets or out-of-scope data in the prompt, the system prompt, or the retrievable corpus in the first place. Filter retrieval results by the requesting user's authorisation before they reach the model.
- Output-side DLP. Run model output through data-loss-prevention checks for secret patterns and PII before it returns to the user or downstream system.
- Per-user retrieval isolation. In RAG, enforce that a user can only retrieve documents they are authorised to see — the vector store must be access-control-aware, not a shared pool (see LLM08).
Where it lives: retrieval/authorisation layer + output filter. How to verify: test that user A cannot elicit user B's data; scan outputs for secret formats in CI against a seeded corpus.
LLM03:2025 — Supply Chain
The risk: the LLM supply chain — base models, fine-tunes, datasets, model-serving dependencies, plugins — carries the same (and some new) integrity risks as any software supply chain. A poisoned model from a hub, a tampered adapter, or a compromised serving dependency all land here.
Controls engineers build:
- Provenance and integrity for models. Pin model versions and verify hashes/signatures the way you pin and verify package dependencies. Know where each weight file came from.
- An SBOM that includes AI components. Extend your bill of materials to models, datasets, and adapters — exactly the "SBOM for AI" direction we covered in the SBOM reference. Regenerate on change; gate the build on drift.
- Vet model and dataset sources. Treat a model hub like a package registry: prefer signed, reputable sources; scan for known-malicious artefacts; don't pull arbitrary weights into a privileged runtime.
Where it lives: build pipeline + model registry + dependency management. How to verify: every model artefact in production traces to a pinned, verified source; SBOM drift fails CI.
LLM04:2025 — Data and Model Poisoning
The risk: pre-training, fine-tuning, or embedding data is manipulated to introduce backdoors, biases, or degraded integrity. Distinct from supply chain in that it targets the data that shapes model behaviour.
Controls engineers build:
- Dataset provenance and versioning. Treat training/fine-tuning/embedding data as a versioned, integrity-checked asset. You cannot reason about poisoning if you cannot say exactly what data produced a given model.
- Pipeline access control. The training and embedding pipeline is a privileged system; who can write to the dataset, trigger a fine-tune, or push an adapter is an access-control question with security consequences.
- Anomaly and behavioural evaluation. Evaluate models against held-out and adversarial test sets before promotion; a backdoored model often passes ordinary benchmarks but fails targeted probes.
Where it lives: MLSecOps — the data and training pipeline. How to verify: reproducible builds from versioned data; pre-promotion eval gates that include adversarial probes.
LLM05:2025 — Improper Output Handling
The risk: insufficient validation and sanitisation of model output before it is passed to a downstream component. This is the classic injection class re-stated for LLMs: the model emits text, and something downstream executes or renders it — a shell, a SQL query, a browser DOM, an eval.
Controls engineers build:
- Treat model output as untrusted input to the next system. Never pass raw LLM output into a shell, SQL,
eval, a template, orinnerHTML. Parameterise, escape, and validate exactly as you would for user input — because that is what it is. - Constrained output formats. Where the model drives a downstream action, force structured output (a typed schema) and validate it, rather than parsing free text.
- Context-aware encoding. Encode for the destination — HTML-escape for a page, parameterise for a database.
Where it lives: the boundary between the model and every downstream consumer. How to verify: assert no code path passes model output to an interpreter/renderer without sanitisation; this is a code-review and SAST target.
LLM06:2025 — Excessive Agency
The risk: the system is granted too much capability, autonomy, or permission, so that an unexpected (or manipulated) model output can take damaging action. This is the agentic-AI risk, and it is where injection turns into impact.
Controls engineers build:
- Minimise tools, permissions, and autonomy — independently. Limit which tools exist, what each can do, and how much the agent can do without a human. Each is a separate dial; turn all three down to the minimum the use case needs.
- Human-in-the-loop for high-impact actions. Irreversible or high-value operations require explicit out-of-band confirmation, not a model decision.
- Capability scoping over trust. Don't rely on the model "deciding" not to misuse a capability; remove the capability or gate it. The control is architectural.
- Per-action authorisation. The agent should act with the user's authority for that specific action, not a broad service account — so the blast radius is bounded by what the user could do anyway.
Where it lives: tool-calling harness + authorisation model + architecture. How to verify: enumerate every tool and its privilege; confirm no single manipulated output can reach an irreversible action unattended.
LLM07:2025 — System Prompt Leakage
The risk: the system prompt is exposed, revealing instructions, logic, or — worse — secrets or credentials that should never have been in it.
Controls engineers build:
- Never put secrets in the system prompt. The primary control is upstream: the system prompt must contain no credentials, keys, or sensitive logic whose disclosure causes harm. Assume it will leak and design accordingly.
- Don't treat the system prompt as a security boundary. Authorisation and access control belong in the application, enforced in code — not asserted in a prompt the model can be coaxed into revealing or ignoring.
Where it lives: prompt construction + application authorisation. How to verify: audit system prompts for secrets/credentials (none permitted); confirm security decisions are enforced in code, not prompt text.
LLM08:2025 — Vector and Embedding Weaknesses
The risk: weaknesses in how vectors and embeddings are generated, stored, or retrieved — the RAG layer. Includes embedding-inversion (recovering source data from vectors), cross-tenant leakage in a shared store, and retrieval of poisoned or unauthorised content.
Controls engineers build:
- Access-control-aware retrieval. The vector store must enforce per-user/per-tenant authorisation on retrieval, not return from a shared pool. This is the same control as LLM02, applied at the embedding layer.
- Protect the embedding store as sensitive data. Embeddings can leak their source; encrypt at rest, control access, and don't treat the vector DB as low-sensitivity infrastructure.
- Validate ingested content. Content entering the corpus is a trust decision (links back to LLM04 poisoning and LLM01 indirect injection) — vet what you embed.
Where it lives: the RAG / vector-store layer. How to verify: cross-tenant retrieval tests; confirm authorisation is enforced at query time.
LLM09:2025 — Misinformation
The risk: the model produces false or misleading output that the application — or the user — relies on. In regulated or high-stakes contexts (health, finance, public sector), acting on confidently-wrong output is a real-world harm, not a quality nit.
Controls engineers build:
- Ground outputs and cite sources. For factual use cases, retrieval-grounding with source attribution lets users (and downstream checks) verify claims rather than trust generation.
- Human oversight proportional to stakes. The higher the consequence of a wrong answer, the more a human-review step is a control, not a courtesy.
- Constrain scope and set expectations. Don't deploy a general model into a high-stakes decision path without guardrails on what it's allowed to assert.
Where it lives: retrieval grounding + UX + human-review workflow. How to verify: measure grounded-vs-ungrounded answer rates; confirm high-stakes paths have a review gate.
LLM10:2025 — Unbounded Consumption
The risk: uncontrolled resource use — the model or its surrounding system can be driven to consume unbounded compute, tokens, or cost. Covers denial-of-service, denial-of-wallet (running up an API bill), and model-extraction via high-volume querying.
Controls engineers build:
- Rate-limit and quota everything. Per-user and global limits on requests, tokens, and cost. Cap maximum input and output length. (The same discipline as any API: our own contact API uses a sliding-window limiter for exactly this reason.)
- Budget controls and alerting. Hard spending caps and anomaly alerts on token/cost spend — denial-of-wallet is a real attack against metered model APIs.
- Throttle to resist extraction. High-volume, systematic querying aimed at distilling the model should trip rate and pattern limits.
Where it lives: API gateway + quota/billing controls + monitoring. How to verify: load-test the limits; confirm a single principal cannot exhaust resources or run unbounded cost.
The throughline
Read the ten controls together and a pattern falls out. The recurring primitives are not model-specific — they are the security engineering you already know, applied to a new component:
- Treat the model as untrusted — its inputs and its outputs (LLM01, LLM05).
- Least privilege and capability scoping — especially for agents (LLM06, LLM07).
- Authorisation-aware data access — at retrieval and embedding (LLM02, LLM08).
- Supply-chain and pipeline integrity — for models and data, not just code (LLM03, LLM04).
- Resource and cost bounding — rate limits, quotas, budgets (LLM10).
- Grounding and human oversight where stakes are high (LLM09).
That is the actual work of securing AI systems: not a new security discipline bolted on, but the translation of established controls onto LLM and agentic architectures — done in the runtime, the pipeline, and the design, with the OWASP list as the map rather than the destination. The teams that do this well are the ones that stop asking "how do we make the model safe?" and start asking "what can this component touch, and what have we put around it?"
Sources
- OWASP GenAI Security Project, OWASP Top 10 for LLM Applications (2025) — canonical list and per-risk detail.
- OWASP, OWASP Top 10 for LLM Applications 2025 (PDF, v2025).
- Related Orizon analysis: Indirect prompt injection in the wild · What is an SBOM? (incl. SBOM for AI).