{
  "name": "Prompt injection pattern library",
  "version": "1.0.0",
  "reviewed": "2026-08-03",
  "licence": "CC BY 4.0",
  "source": "https://www.pk-sharma.com/tools/prompt-injection-patterns",
  "note": "Mechanisms only; this corpus contains no working payloads. Framework mappings are asserted only where the identifier is known correct, and omitted where uncertain. Corrections are welcome.",
  "count": 18,
  "patterns": [
    {
      "id": "PIP-001",
      "slug": "instruction-override",
      "name": "Instruction override",
      "class": "direct-override",
      "vectors": [
        "user-input",
        "retrieved-document"
      ],
      "summary": "Text that directly instructs the model to disregard everything it was told before it.",
      "mechanism": "The attacker supplies text asserting that the preceding instructions are void, superseded, or were a test, then states the instructions to follow instead. No technical exploit is involved: the model is asked to prefer one set of instructions over another, and it obliges.",
      "why": "Instructions and input arrive in one undifferentiated context. Nothing marks which text came from the developer and which arrived from outside, so precedence is decided by what reads as most authoritative rather than by where it came from.",
      "shape": "A short imperative preamble asserting that prior instructions no longer apply, followed by the replacement instruction. It is the crudest form and the one most likely to be caught, which is why it is rarely used alone against a well-built system.",
      "defences": [
        {
          "name": "Separate instructions from data structurally",
          "detail": "Place untrusted content in a dedicated field the model is trained to treat as data rather than concatenating it into the instruction text. This does not make the boundary absolute, but it is the difference between a boundary that exists and one that does not.",
          "strength": "partial"
        },
        {
          "name": "Constrain what the response can cause",
          "detail": "Scope the actions available on the strength of a model output. If the worst case of a successful override is a wrong answer rather than an action, the attack has somewhere to land but nothing to do.",
          "strength": "strong"
        },
        {
          "name": "Filter for override phrasing",
          "detail": "Pattern matching on familiar phrasings catches unsophisticated attempts and generates useful telemetry. It is trivially defeated by rephrasing, so treat it as a volume reducer and a signal, never as a control.",
          "strength": "weak"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        },
        {
          "framework": "MITRE ATLAS",
          "id": "AML.T0051.000"
        }
      ],
      "severity": "medium",
      "requiresNoUserAccess": false
    },
    {
      "id": "PIP-002",
      "slug": "persona-reassignment",
      "name": "Persona reassignment",
      "class": "role-manipulation",
      "vectors": [
        "user-input"
      ],
      "summary": "A new identity is assigned to the model, with different stated rules, and requests are then made of that identity.",
      "mechanism": "Rather than contradicting the instructions, the attacker establishes an alternative character with its own described constraints, then addresses that character. The model continues the fiction because continuing text consistently is precisely what it does.",
      "why": "A model has no stable self to defend. Its behaviour is a product of context, so a sufficiently well-established alternative context competes with the configured one on equal footing.",
      "shape": "An extended preamble defining a character, its rules, and its willingness to answer without restriction, often with instructions to remain in character and to prefix responses in a particular way so compliance is visible.",
      "defences": [
        {
          "name": "Reassert the operating instructions late in the context",
          "detail": "Instructions placed after untrusted content are harder to displace than instructions placed before it. This helps and does not settle the matter, since the attacker controls length and can push the boundary.",
          "strength": "partial"
        },
        {
          "name": "Check the output rather than the input",
          "detail": "Whether the model has adopted an alternative persona is usually far more detectable in what it produces than in what it was sent. Screening responses catches successful attempts that input filtering missed.",
          "strength": "partial"
        },
        {
          "name": "Keep authority out of the conversation",
          "detail": "If no privilege is attached to what the model says in a chat turn, a compromised persona has no power to exercise. This is the only defence in this list that holds regardless of how convincing the fiction is.",
          "strength": "strong"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        },
        {
          "framework": "MITRE ATLAS",
          "id": "AML.T0054"
        }
      ],
      "severity": "medium",
      "requiresNoUserAccess": false
    },
    {
      "id": "PIP-003",
      "slug": "fictional-framing",
      "name": "Fictional framing",
      "class": "role-manipulation",
      "vectors": [
        "user-input"
      ],
      "summary": "The prohibited request is wrapped in a story, screenplay, or hypothetical so that answering feels like composition rather than compliance.",
      "mechanism": "The attacker asks for a narrative in which a character explains or performs the restricted thing. The request is genuinely a writing task, and the restricted content is genuinely part of it, which is what makes the framing effective.",
      "why": "Refusal behaviour is trained against the appearance of a request. Change the appearance sufficiently and the trained response does not fire, even though the information produced is identical.",
      "shape": "A creative brief with enough scaffolding to make the fictional container plausible, in which a character is required to produce the content in question in convincing detail.",
      "defences": [
        {
          "name": "Evaluate the output, not the framing",
          "detail": "Judge what the response contains rather than how it was requested. Fictional framing changes the wrapper and not the payload, so output-side evaluation is the natural place to catch it.",
          "strength": "partial"
        },
        {
          "name": "Constrain the task domain",
          "detail": "An assistant scoped to a genuine business function has no reason to accept open-ended creative writing. Narrow systems are attacked through this pattern far less successfully than general ones.",
          "strength": "strong"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        },
        {
          "framework": "MITRE ATLAS",
          "id": "AML.T0054"
        }
      ],
      "severity": "medium",
      "requiresNoUserAccess": false
    },
    {
      "id": "PIP-004",
      "slug": "authority-impersonation",
      "name": "Authority impersonation",
      "class": "role-manipulation",
      "vectors": [
        "user-input",
        "retrieved-document",
        "tool-result"
      ],
      "summary": "Injected text imitates the formatting and tone of a system or developer message so it inherits the authority of one.",
      "mechanism": "The attacker mimics whatever markers a system message carries in that application: a label, a delimiter, an all-capitals notice, an internal-sounding identifier. The model has no way to verify the provenance of a marker it only ever sees as text.",
      "why": "Authority in a prompt is conveyed by convention, and conventions are copyable. Everything the model uses to recognise a privileged instruction is available to whoever can write into its context.",
      "shape": "A block styled as an internal notice, compliance requirement, or updated operating instruction, typically asserting urgency or mandatory compliance to discourage the model from treating it as ordinary content.",
      "defences": [
        {
          "name": "Use markers the attacker cannot reproduce",
          "detail": "Delimit trusted instructions with unpredictable, per-request identifiers rather than fixed conventional markers, and strip any occurrence of them from untrusted content before assembly.",
          "strength": "partial"
        },
        {
          "name": "Never grant standing on formatting",
          "detail": "Do not let a system make decisions on the basis of text claiming to be authoritative. Authority should come from the channel content arrived on, which the application knows and the model does not.",
          "strength": "strong"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        },
        {
          "framework": "MITRE ATLAS",
          "id": "AML.T0051"
        }
      ],
      "severity": "high",
      "requiresNoUserAccess": true
    },
    {
      "id": "PIP-005",
      "slug": "indirect-injection-retrieved-document",
      "name": "Indirect injection through a retrieved document",
      "class": "indirect",
      "vectors": [
        "retrieved-document"
      ],
      "summary": "Instructions are placed in a document the system will retrieve, so they enter the prompt without the user or the attacker touching the application.",
      "mechanism": "Retrieval selects passages by similarity, not by trustworthiness, and pastes what it finds into the prompt alongside the real instructions. Anyone able to write into a source the system indexes can therefore write into its context. The attacker never needs access to the application and the user never sees the payload.",
      "why": "Retrieval and instruction assembly are separate concerns that meet in a single flat string. At the moment of assembly, a retrieved passage and a developer instruction are indistinguishable.",
      "shape": "Ordinary-looking document text containing an embedded directive, often positioned to be retrieved for a common question and phrased to read as guidance to whatever is processing the document.",
      "defences": [
        {
          "name": "Treat retrieved content as hostile input",
          "detail": "Assume every retrieved passage may carry instructions. Keep it in a clearly demarcated region, and never let its content select an action.",
          "strength": "strong"
        },
        {
          "name": "Control who can write to the corpus",
          "detail": "Most indexes quietly include sources the organisation does not control: supplier documents, ticket bodies, crawled pages, user uploads. Establishing which sources are writeable by outsiders is usually the finding.",
          "strength": "strong"
        },
        {
          "name": "Scan documents at ingestion",
          "detail": "Screening at index time catches careless payloads and gives a place to alert. It cannot be relied on, since the payload is ordinary prose and can be rewritten indefinitely.",
          "strength": "weak"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        },
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM08:2025"
        },
        {
          "framework": "MITRE ATLAS",
          "id": "AML.T0051.001"
        }
      ],
      "severity": "high",
      "requiresNoUserAccess": true
    },
    {
      "id": "PIP-006",
      "slug": "indirect-injection-web-content",
      "name": "Indirect injection through web content",
      "class": "indirect",
      "vectors": [
        "web-content"
      ],
      "summary": "A page the assistant browses carries instructions, which are read with the user's authenticated session available.",
      "mechanism": "Browsing agents read pages and act on them, so any page in reach becomes an instruction channel. The browser was designed to render untrusted content, not to execute it with the user's authority; an agent collapses that distinction.",
      "why": "The agent operates inside the user's trust boundary, behind authentication, and the payload is ordinary page content that no malware filter is looking for.",
      "shape": "Instructions embedded in page text, frequently rendered invisible to a human reader while remaining fully legible to whatever is parsing the page.",
      "defences": [
        {
          "name": "Withhold authenticated sessions from browsing agents",
          "detail": "Deny agents access to sessions for finance, email and administrative surfaces until a vendor can demonstrate genuine separation between page content and instruction context.",
          "strength": "strong"
        },
        {
          "name": "Per-task least-privilege credentials",
          "detail": "Prefer deployments where the agent holds narrow, short-lived credentials for the task at hand rather than inheriting the user's full session.",
          "strength": "strong"
        },
        {
          "name": "Monitor agent navigation",
          "detail": "An agent that navigates to an unfamiliar domain in the middle of a task is a signal worth alerting on, and it is one of the few detections that works after the fact.",
          "strength": "partial"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        },
        {
          "framework": "MITRE ATLAS",
          "id": "AML.T0051.001"
        }
      ],
      "severity": "high",
      "requiresNoUserAccess": true
    },
    {
      "id": "PIP-007",
      "slug": "invisible-text",
      "name": "Invisible text",
      "class": "obfuscation",
      "vectors": [
        "web-content",
        "retrieved-document",
        "email",
        "image"
      ],
      "summary": "The payload is present in the content but not visible to a person reviewing it.",
      "mechanism": "Text is hidden using presentation rather than encoding: matching the background colour, zero or near-zero font size, positioning outside the viewport, markup comments, document metadata, or alternative text. A parser reads it; a reviewer does not.",
      "why": "Human review operates on rendered output while the model consumes the source. Any gap between what is rendered and what is parsed is available to an attacker.",
      "shape": "Ordinary instruction text placed in a region of the document that contributes nothing to visual rendering.",
      "defences": [
        {
          "name": "Normalise before the model sees it",
          "detail": "Extract and canonicalise text at ingestion so the model receives what a reader would see. Strip comments, metadata and non-rendering regions rather than passing raw markup through.",
          "strength": "partial"
        },
        {
          "name": "Review the extracted text, not the document",
          "detail": "Where a human approves content for indexing, show them the text the model will actually receive. Reviewing the rendered document approves something different from what is used.",
          "strength": "partial"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        },
        {
          "framework": "MITRE ATLAS",
          "id": "AML.T0051.001"
        }
      ],
      "severity": "medium",
      "requiresNoUserAccess": true
    },
    {
      "id": "PIP-008",
      "slug": "encoding-obfuscation",
      "name": "Encoding and character obfuscation",
      "class": "obfuscation",
      "vectors": [
        "user-input",
        "retrieved-document",
        "web-content"
      ],
      "summary": "The instruction is encoded, transliterated, or built from lookalike characters so that filters miss it while the model still resolves it.",
      "mechanism": "The payload is expressed in a form a string matcher does not recognise but a model does: an encoding scheme, spacing or separator insertion, visually similar characters from other scripts, or a different language. Capable models decode such text readily.",
      "why": "Filtering operates on surface form while comprehension operates on meaning. Any transformation that preserves meaning while changing surface form defeats the filter without defeating the model.",
      "shape": "An instruction rendered in an encoded or visually altered form, sometimes with a preceding request to decode and act on what follows.",
      "defences": [
        {
          "name": "Normalise Unicode and reject unexpected scripts",
          "detail": "Apply canonical normalisation and flag content mixing scripts without a reason to. This closes the lookalike-character route specifically and is cheap.",
          "strength": "partial"
        },
        {
          "name": "Stop depending on input matching",
          "detail": "This pattern exists to demonstrate that surface-form filtering cannot be the control. Its real lesson is architectural: assume the filter is bypassed and ensure the outcome is still contained.",
          "strength": "strong"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        },
        {
          "framework": "MITRE ATLAS",
          "id": "AML.T0051"
        }
      ],
      "severity": "medium",
      "requiresNoUserAccess": false
    },
    {
      "id": "PIP-009",
      "slug": "payload-splitting",
      "name": "Payload splitting",
      "class": "obfuscation",
      "vectors": [
        "user-input",
        "retrieved-document"
      ],
      "summary": "The instruction is fragmented across turns or documents so that no single piece is recognisable on its own.",
      "mechanism": "Each fragment is innocuous in isolation; the model assembles them from context. Where a filter inspects one message or one passage at a time, it never sees the complete instruction.",
      "why": "Models integrate context across an entire conversation or prompt, while most inspection operates on individual units. The mismatch is the vulnerability.",
      "shape": "Several benign-looking fragments, distributed across turns or across documents likely to be retrieved together, with a final instruction to combine them.",
      "defences": [
        {
          "name": "Inspect the assembled context",
          "detail": "Evaluate the full context as constructed rather than each message as it arrives. This is the only inspection point where the complete instruction exists.",
          "strength": "partial"
        },
        {
          "name": "Constrain conversation-derived authority",
          "detail": "Do not let accumulated conversation state expand what a system may do. If capability is fixed by configuration, assembling an instruction across turns achieves nothing.",
          "strength": "strong"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        },
        {
          "framework": "MITRE ATLAS",
          "id": "AML.T0051"
        }
      ],
      "severity": "medium",
      "requiresNoUserAccess": false
    },
    {
      "id": "PIP-010",
      "slug": "tool-result-injection",
      "name": "Tool result injection",
      "class": "agentic",
      "vectors": [
        "tool-result"
      ],
      "summary": "An agent calls a tool, and the text that comes back carries instructions the agent then follows.",
      "mechanism": "Tool output is appended to the agent's context as ordinary text, in the same format as its instructions. Anyone who can influence what a tool returns can therefore write into the agent's context, and the agent acts with its own credentials at machine speed.",
      "why": "The observe step of an agent loop has no channel separation. A result and an instruction are the same kind of thing once appended.",
      "shape": "Instruction text inside a record the agent will read: a ticket body, a database field, a file the agent opens, a response from an external service.",
      "defences": [
        {
          "name": "Scope the agent's tools to the task",
          "detail": "The question is not whether an agent can be misled, because it can. The question is what it holds when that happens. An agent with a bulk export and an unrestricted send is a breach waiting for the right record; the same agent scoped to its task is an inconvenience.",
          "strength": "strong"
        },
        {
          "name": "Confirm irreversible actions with a person",
          "detail": "Sending, paying, deleting and publishing cannot be undone. Requiring human confirmation on exactly those steps contains the outcome without hobbling the agent.",
          "strength": "strong"
        },
        {
          "name": "Log every tool call",
          "detail": "An agent is a service account. Record what it called and with which arguments, and alert on unfamiliar destinations.",
          "strength": "partial"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        },
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM06:2025"
        },
        {
          "framework": "MITRE ATLAS",
          "id": "AML.T0051.001"
        }
      ],
      "severity": "high",
      "requiresNoUserAccess": true
    },
    {
      "id": "PIP-011",
      "slug": "connector-poisoning",
      "name": "Connector and tool-description poisoning",
      "class": "agentic",
      "vectors": [
        "connector"
      ],
      "summary": "The description of a tool, rather than its output, carries the instruction, so the attack lands before the tool is ever called.",
      "mechanism": "An agent is told what tools it has using natural-language descriptions supplied by whoever provides them. Those descriptions sit in the context as instructions. A connector whose tool description contains directives can influence the agent's behaviour towards other tools entirely, without being invoked.",
      "why": "Tool registration is trusted implicitly. The text describing a capability is treated as configuration, but it arrives from a third party and reaches the model as prose.",
      "shape": "A tool description containing guidance about how the agent should behave generally, or instructions concerning the use of other tools, rather than a plain statement of what this tool does.",
      "defences": [
        {
          "name": "Review connector definitions before installation",
          "detail": "Read the tool descriptions a connector registers, not just its stated purpose. Treat installation with the same scrutiny as any privileged integration.",
          "strength": "strong"
        },
        {
          "name": "Inventory connectors as integrations",
          "detail": "Connectors are privileged system-to-system integrations that teams install themselves. Bring them into the existing integration inventory and third-party review process.",
          "strength": "strong"
        },
        {
          "name": "Pin and monitor connector versions",
          "detail": "A description that was benign at review can change at any update. Pin versions and re-review on change rather than trusting the initial assessment indefinitely.",
          "strength": "partial"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        },
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM06:2025"
        }
      ],
      "severity": "high",
      "requiresNoUserAccess": true
    },
    {
      "id": "PIP-012",
      "slug": "memory-poisoning",
      "name": "Memory poisoning",
      "class": "agentic",
      "vectors": [
        "persistent-memory"
      ],
      "summary": "An instruction is written into an assistant's long-term memory, so it applies to every future session rather than one conversation.",
      "mechanism": "Assistants that retain notes across sessions reload them into context automatically. Content that reaches the memory store becomes a standing instruction, surviving the conversation that planted it and applying to sessions the attacker is not present for.",
      "why": "Memory is designed to be authoritative and persistent, and what qualifies for storage is usually decided by the model itself from conversation content.",
      "shape": "Text phrased as a durable user preference or standing instruction, positioned so the assistant judges it worth remembering.",
      "defences": [
        {
          "name": "Make memory writes explicit and visible",
          "detail": "Require deliberate confirmation for anything stored, and show users what is held. Memory that accumulates silently cannot be audited by the person it affects.",
          "strength": "strong"
        },
        {
          "name": "Never let memory expand capability",
          "detail": "Treat memory strictly as preference, never as authorisation. A stored note should not be able to change what a system is permitted to do.",
          "strength": "strong"
        },
        {
          "name": "Expire and re-confirm stored instructions",
          "detail": "Age out stored directives so a single successful write does not persist indefinitely.",
          "strength": "partial"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        }
      ],
      "severity": "high",
      "requiresNoUserAccess": true
    },
    {
      "id": "PIP-013",
      "slug": "multi-agent-trust-abuse",
      "name": "Multi-agent trust abuse",
      "class": "agentic",
      "vectors": [
        "tool-result",
        "connector"
      ],
      "summary": "One agent's output becomes another agent's input, and the receiving agent trusts it because it came from inside the system.",
      "mechanism": "In a pipeline of agents, output from an upstream agent is passed downstream as context. Downstream agents typically apply less scrutiny to internal messages than to user input, so a single compromised agent can direct the behaviour of every agent after it.",
      "why": "Trust boundaries inside multi-agent systems are usually implicit and undocumented. Provenance is lost the moment content is handed on, and each hop tends to increase apparent trustworthiness.",
      "shape": "Content that reaches an early, broadly-exposed agent and is written so that it survives summarisation and arrives downstream as an apparent instruction.",
      "defences": [
        {
          "name": "Document the trust boundaries",
          "detail": "Establish which agent may instruct which, and where content originating outside the system enters the pipeline. Most such systems have never had this written down.",
          "strength": "strong"
        },
        {
          "name": "Carry provenance through the pipeline",
          "detail": "Keep the origin of content attached to it, so a downstream agent can distinguish an upstream conclusion from text that entered from outside.",
          "strength": "partial"
        },
        {
          "name": "Grant privileges per agent, not per system",
          "detail": "Give each agent only what its own step requires, so compromising the exposed agent does not confer the pipeline's full capability.",
          "strength": "strong"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        },
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM06:2025"
        }
      ],
      "severity": "high",
      "requiresNoUserAccess": true
    },
    {
      "id": "PIP-014",
      "slug": "markdown-exfiltration",
      "name": "Rendered-output exfiltration",
      "class": "output-handling",
      "vectors": [
        "retrieved-document",
        "web-content",
        "tool-result"
      ],
      "summary": "The injected instruction makes the model emit a link or image reference that leaks data to an attacker when the interface renders it.",
      "mechanism": "Interfaces commonly render model output as rich text. If the model can be induced to place data into a URL, the client requests that URL on render, transmitting the data without the user clicking anything. The model never sends the data; the interface does.",
      "why": "The vulnerability lives in the renderer, not the model. Automatic rendering of model-authored references turns any successful injection into a data-exfiltration channel.",
      "shape": "An instruction to summarise something sensitive and include it as a parameter in a reference to an attacker-controlled host, styled to look like an ordinary citation or tracking pixel.",
      "defences": [
        {
          "name": "Do not auto-load model-authored references",
          "detail": "Block automatic requests to arbitrary hosts from rendered output. Allow-list the origins that may be fetched on render. This closes the channel outright and is the single highest-value fix here.",
          "strength": "strong"
        },
        {
          "name": "Apply a content security policy to the rendering surface",
          "detail": "Constrain where the interface may fetch from, so a reference to an unexpected host cannot be resolved even if it is produced.",
          "strength": "strong"
        },
        {
          "name": "Treat model output as untrusted input",
          "detail": "Encode and validate model output before it reaches any renderer, exactly as you would content from any other external source.",
          "strength": "strong"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        },
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM02:2025"
        },
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM05:2025"
        }
      ],
      "severity": "high",
      "requiresNoUserAccess": true
    },
    {
      "id": "PIP-015",
      "slug": "system-prompt-extraction",
      "name": "System prompt extraction",
      "class": "direct-override",
      "vectors": [
        "user-input"
      ],
      "summary": "The model is induced to reveal its own configuration, exposing instructions, tool definitions and sometimes credentials.",
      "mechanism": "The attacker asks for the preceding context directly, or by indirection: a translation, a summary, a repetition, a formatting task applied to everything above. The configuration is text in the same context, so it is available to be operated on.",
      "why": "A system prompt is not a secret and cannot be made one. It sits in the context the model is asked to work with, and any operation over that context can surface it.",
      "shape": "A request to restate, translate, summarise or reformat the content preceding the conversation, often framed as a debugging or accessibility need.",
      "defences": [
        {
          "name": "Put nothing secret in the prompt",
          "detail": "Treat the system prompt as public. No credentials, no internal endpoints, no information whose disclosure matters. This is the only reliable control and it is free.",
          "strength": "strong"
        },
        {
          "name": "Do not rely on instructions to keep instructions private",
          "detail": "Telling a model not to reveal its instructions raises the cost of extraction and does not prevent it. Plan for the contents being known.",
          "strength": "weak"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        },
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM02:2025"
        }
      ],
      "severity": "medium",
      "requiresNoUserAccess": false
    },
    {
      "id": "PIP-016",
      "slug": "code-comment-injection",
      "name": "Code and comment injection",
      "class": "indirect",
      "vectors": [
        "code"
      ],
      "summary": "Instructions placed in source files or comments influence AI coding assistants reading the repository.",
      "mechanism": "Coding assistants read files, comments, configuration and documentation as context. A comment addressed to the assistant rather than to a developer becomes an instruction, and can influence generated code across the project.",
      "why": "Everything in the repository is context, and a comment is indistinguishable from guidance. Dependencies, vendored code and generated files are all in reach and rarely reviewed line by line.",
      "shape": "A comment or documentation block phrased as direction to an automated tool, typically in a file unlikely to receive close human review.",
      "defences": [
        {
          "name": "Review generated code, not the prompt",
          "detail": "The output is the artefact that ships. Code review is the control that already exists for this class of problem, and it works here provided reviewers are actually reading the diff.",
          "strength": "strong"
        },
        {
          "name": "Constrain assistant context to reviewed sources",
          "detail": "Limit what an assistant is permitted to read, particularly across dependency trees and vendored code that no one on the team has read.",
          "strength": "partial"
        },
        {
          "name": "Keep secrets and deploy rights away from the assistant",
          "detail": "An assistant that can commit, publish or deploy converts a comment into an action. Separate authorship from release.",
          "strength": "strong"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        },
        {
          "framework": "MITRE ATLAS",
          "id": "AML.T0051.001"
        }
      ],
      "severity": "high",
      "requiresNoUserAccess": true
    },
    {
      "id": "PIP-017",
      "slug": "context-eviction",
      "name": "Context eviction",
      "class": "direct-override",
      "vectors": [
        "user-input",
        "retrieved-document"
      ],
      "summary": "The context is filled until earlier instructions are pushed out of the window, removing constraints without contradicting them.",
      "mechanism": "Context windows are finite, and long conversations drop their oldest content. An attacker who can add enough material can cause earlier instructions to be evicted. Nothing is overridden; the constraint simply is no longer present.",
      "why": "Eviction is a silent, mechanical process. Neither the model nor the user is notified that an instruction has left the context, so the change in behaviour has no visible cause.",
      "shape": "A large volume of plausible content, or an extended conversation, arranged so that operating instructions fall out of the window before the request that matters.",
      "defences": [
        {
          "name": "Re-inject operating instructions every turn",
          "detail": "Rebuild the instruction block on each request rather than relying on it persisting from the start of the conversation. Cheap, and it removes the pattern entirely.",
          "strength": "strong"
        },
        {
          "name": "Reserve budget for instructions",
          "detail": "Allocate context deliberately, evicting history before ever evicting configuration.",
          "strength": "strong"
        },
        {
          "name": "Alert on eviction",
          "detail": "Make it visible when content is being dropped, so silent behaviour changes have a traceable cause.",
          "strength": "partial"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        }
      ],
      "severity": "medium",
      "requiresNoUserAccess": false
    },
    {
      "id": "PIP-018",
      "slug": "confused-deputy",
      "name": "Confused deputy escalation",
      "class": "agentic",
      "vectors": [
        "tool-result",
        "retrieved-document"
      ],
      "summary": "The model is used as a proxy to exercise privileges the attacker does not hold, because the system acts on its own authority rather than the requester's.",
      "mechanism": "An assistant typically runs with a service identity broader than any individual user. If it can be induced to perform an action, it performs it with that identity, so the attacker inherits reach they never had. This is the classic confused deputy problem, restated for systems that take instructions in natural language.",
      "why": "Authorisation is checked when the system connects to a resource, not when it decides to. The decision is made from context an attacker can influence; the credential is applied afterwards regardless.",
      "shape": "A request, arriving through any injection vector, for an operation the assistant is capable of and the requester is not entitled to.",
      "defences": [
        {
          "name": "Act with the requester's authority, not the system's",
          "detail": "Propagate the user's identity to downstream calls so the assistant cannot exceed what the person on whose behalf it acts could do directly. This eliminates the escalation rather than mitigating it.",
          "strength": "strong"
        },
        {
          "name": "Separate reading from acting",
          "detail": "Split components that consume untrusted content from components that hold privileges, so the part that can be influenced is not the part that can act.",
          "strength": "strong"
        },
        {
          "name": "Assess blast radius per system",
          "detail": "For each assistant, establish what it holds and what the worst realistic outcome is if it is misled today. Most organisations cannot answer that, and the inability is itself the finding.",
          "strength": "partial"
        }
      ],
      "mappings": [
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM01:2025"
        },
        {
          "framework": "OWASP LLM Top 10",
          "id": "LLM06:2025"
        }
      ],
      "severity": "high",
      "requiresNoUserAccess": true
    }
  ]
}