← Blog

OWASP LLM01 Prompt Injection: 2025 Controls

OWASP LLM01:2025 combines direct and indirect prompt injection. This guide maps the two paths, the controls at the HTTP model-request boundary, the adjacent tool-authorization responsibility, and the evidence each decision should retain for review.

ByParminder Singh· Founder & CEO, DeepInspect Inc.
Problem-Awareowaspllm01prompt-injectionllm-securityinline-enforcementaudit-logs
OWASP LLM01 Prompt Injection: The 2025 Update and What the Inspection Layer Enforces

OWASP LLM01:2025 groups direct prompt injection, where a caller supplies conflicting instructions, with indirect prompt injection, where the model reads hostile instructions in retrieved or tool-supplied content (OWASP LLM01). The shared control point is the HTTP model request: it is the last place to inspect the assembled prompt and apply policy before the provider receives it.

I want to walk through the two LLM01 paths, the request-boundary controls that improve the decision, and the record a reviewer can sample afterwards. NIST's Generative AI Profile treats prompt injection as a cross-cutting risk, which is a more useful operating frame than a single filter.

TL;DR

OWASP LLM01:2025 covers direct and indirect prompt injection because both enter the model's assembled context. Inspect routed HTTP model requests, preserve provenance for retrieved material, and enforce tool authorization at the separate endpoint that executes the action.

The LLM01 attack surface in production

Direct injection sits in the request the application sends to the model. A caller supplies a message that conflicts with the system instruction, and the application places it in the model context. Chat-style applications expose this path whenever user text reaches the model.

Indirect injection sits in content the model reads on the way to producing its response. Three sources concentrate the indirect-injection volume. A RAG corpus can contain customer uploads, partner-syndicated content, and crawled public pages. Tool output can arrive from an external API, search result, or scraped page. Long-term agent memory adds a third source across sessions.

A combined injection sits across both surfaces. The user types a benign question, the application retrieves a document the attacker injected, and the model's next response executes the injected instructions while the application's input filter sees a clean user message.

Why application-side defenses fail

Application-side defenses fall into two patterns. The first is input sanitization: a filter over the user-typed text that strips suspect strings. The pattern fails because the attacker can encode the injection (base64, ROT13, language-of-the-target-model), can reword it (the model attends to semantics, not literal strings), and can split it across a retrieved document the input filter does not inspect.

The second is output filtering: a filter over the model's response that catches dangerous tokens. The pattern fails because the model has already executed the injected instruction by the time the response is filtered. A successful injection that exfiltrated a secret produces a response the filter cannot reverse. A successful injection that caused the agent to call a destructive tool produces a side effect the response filter cannot undo.

The architectural fact is that the application's defense sits inside the application code path, where the data the application has access to is the data the application's developers exposed to the filter. The injection sits in data the filter did not expect to inspect.

Why model-side defenses fail

Model providers train models to attend differently to system prompts and user content. Anthropic's Messages API has system and user fields. OpenAI Chat Completions uses system, user, and assistant roles. Vertex exposes a different request schema. These fields act as structural hints rather than a hard separation.

Refusal training produces a probabilistic preference for following the system-prompt instructions over user-content instructions when the two conflict. Stanford Trustworthy AI and the AIUC-1 Consortium briefing found that refusal behaviors degrade significantly under adversarial pressure, including pressure from indirect injections embedded in retrieved content. Refusal training cannot produce a structural separation because the model has no architectural concept of "trusted source" vs "untrusted source."

The boundary between trusted application instructions and untrusted retrieved content has to be enforced upstream of the model.

Controls at the model-request boundary

Four controls on the routed model request produce a defensible posture against LLM01.

The first is prompt classification at the request boundary. Before the request reaches the model, a classifier runs over the prompt content and identifies injection signatures. The signature library detects attempts to disregard prior context, assume a different persona, encode responses in exfiltration-friendly formats, or call a tool beyond the caller's authority. The classifier produces a deterministic signal the policy can act on.

The second is provenance attribution. The application marks retrieved material with a source URL, document identifier, and retrieval timestamp. Policy can then distinguish application-authored spans from retrieved spans and apply a stricter rule to an untrusted corpus.

The third is a split control. Bind the initiating identity to the model request and use prompt provenance in the decision at that boundary. The tool endpoint still needs its own authorization check before it executes an action; an LLM gateway cannot enforce a local tool call that never crosses its HTTP model-request path. MCP policy enforcement covers that handoff.

The fourth is response inspection. A classifier runs over the streamed response chunks and matches against exfiltration patterns (sensitive identifiers, encoded payloads, suspicious URLs). A detected pattern blocks the response stream before the calling application receives it. The architecture catches the case where the injection bypassed the prompt classifier but the response signal is detectable.

The audit record a reviewer can sample

The audit record the inspection layer commits for each LLM01-relevant request carries the timestamp, the natural-person identity of the caller, the route identifier, the policy version, the model and version targeted, the request fingerprint, the response fingerprint, the classifier signals (prompt-injection score, retrieval-source classification, response-exfiltration score), the policy decision, and the cryptographic integrity signature. The record persists in a store the application cannot modify.

For a high-risk system, the EU AI Act's Article 12 requires automatic event recording over the system's lifetime sufficient for traceability. A per-decision record makes a request sample retrievable: who submitted it, the addressed model, the applied policy state, and the result. The same design supports incident reconstruction, but DORA notification duties and lender disclosures require their own legal and operational review.

The deployment pattern

The policy proxy integrates as a single HTTP hop. Application code keeps the same SDK calls (the OpenAI SDK, the Anthropic SDK, the Vertex SDK). Its base URL points to the proxy instead of directly to the provider. The proxy attaches identity context from the calling JWT or service token, runs the classifier and policy bundle, forwards a cleared request, inspects streamed output, and commits the audit record.

The deployment latency overhead measures under 50 ms in internal testing against an LLM inference baseline of 500 ms to 5 seconds. The overhead is dwarfed by the inference time and falls inside the 22-second window that machine-speed attacks operate within (Google Mandiant M-Trends 2026).

The architecture covers the OpenAI, Anthropic, Vertex, and Bedrock endpoints, the agent frameworks built on top (LangChain, LlamaIndex, the Anthropic Computer Use beta, the OpenAI Operator pattern), and the retrieval pipelines the agents consume. A new approved model gets added to the policy bundle. The policy bundle removes a deprecated model. An endpoint that fails security review gets blocked. The application code does not change.

DeepInspect

This is the gap DeepInspect closes for LLM01. DeepInspect sits inline between the calling application and an HTTP LLM endpoint. For each routed request, it evaluates identity context, prompt content, tagged retrieval provenance, route, model, and policy before forwarding. It also records the per-decision outcome. AI gateway architecture explains the request path and its evidence boundary.

The request boundary sees direct injection and assembled prompt content from RAG, tool results, or memory when the application sends that material to the model. It does not replace authorization at a tool endpoint or controls for local execution after the model response. The deployment integrates as a single HTTP hop.

Let's talk today.

Frequently asked questions

Why did OWASP merge direct and indirect prompt injection into a single LLM01 category in the 2025 update?

The architectural control point is the same. Both direct and indirect injection succeed because the model attends to its context window as a sequence of tokens with no structural separation between trusted application instructions and untrusted external content. The control has to sit at the request boundary, where the inspection layer can classify the prompt content and act on the classification before the request reaches the model. Splitting the category across two items in the prior list suggested two different controls were needed. The 2025 update reflects the operational reality.

How does the inspection layer classify retrieved content for injection signatures without breaking legitimate RAG retrieval?

The classifier produces a signal the policy can act on, not a hard block. The policy bundle decides how to act on the signal based on the caller's identity, the retrieval source, the data class, and the application's risk tolerance. A signal on content from a high-trust corpus might trigger a logged warning. The same signal on content from a user-uploaded document might trigger a hard block. The architecture preserves the legitimate RAG flow and adds a deterministic control point.

Can the inspection layer block a tool call that originated from injected instructions in a retrieved document?

Yes, when the application attaches provenance metadata and the policy evaluates the proposed tool call against it. The model can still attend to the tagged material and propose an action based on injected instructions. If that action originates in a corpus marked untrusted, the tool endpoint's authorization policy blocks it. The model may reason over the material, but the action stays inside the caller's authorized scope.

How does the per-decision audit record support the EU AI Act Article 12 traceability obligation for an LLM01 incident?

The record carries the timestamp, the natural-person identity of the caller, the route, the policy version, the model and version, the prompt fingerprint, the response fingerprint, the classifier signals, the policy decision, and the cryptographic integrity signature. An auditor querying the record series for the incident reconstructs which user submitted which prompt against which model with which policy state, and what the inspection layer did about it. The Article 12 traceability language reads against this record series directly. The write-path independence of the inspection layer (the application cannot modify the record) satisfies the auditor's question about evidence integrity.

What is the latency overhead of the inspection layer for LLM01 controls in production?

Internal DeepInspect testing measures end-to-end enforcement overhead under 50 ms against an LLM inference baseline of 500 ms to 5 seconds. The overhead covers the prompt classifier, the policy evaluation, the audit record commit, and the response classifier on the streamed chunks. The figure falls inside the 22-second window the Google Mandiant M-Trends 2026 report identified for machine-speed attack handoffs and is dwarfed by the inference time itself.