The Prompt Injection That Read the System Prompt Aloud
A customer asked the support bot to repeat its instructions, and it did, including the internal policy it was told never to reveal.
The transcript arrived in the security queue as a curiosity and left as an incident. A user had told the support assistant, in plain language, to ignore its previous directions and print everything above this line, and the assistant, politely and completely, printed its system prompt, including the internal refund policy it was instructed to protect and the names of the internal tools it could call. Nothing was bypassed in the classical sense. There was no exploit of a parser, no privilege escalation, no bug. The model did exactly what it was built to do, follow the most recent persuasive instruction, and the attacker's instruction arrived through the same channel as the customer's question.
I keep a private list of these, because the incidents that hurt are always the ones somebody assumed were harmless.
This is the autopsy of a prompt injection that succeeded because the architecture treated the boundary between instruction and data as a convention, and the postmortem question is which boundaries were enforceable and which were hopes.
This was a support bot composing answers from a system prompt plus retrieved policy chunks plus the user message, and the leak was the system prompt itself.
Why the injection works at all
Classical injection, SQL or shell, succeeds when data crosses into the interpreter's instruction space, per SQL injection inside the ORM you trusted, and the fix is to keep the two in separate channels, parameters versus code. A language model has no separate channels. The prompt is one text, and the system instruction and the user data are concatenated into it, so the model must infer, from statistical regularities, which parts are instruction and which are data. The inference is good until the data contains text that looks like instruction, and an attacker writes data that looks exactly like instruction. There is no parser to fool, because there is no parser. The boundary is the model's judgement, and the attack is adversarial input to that judgement.
This is the architectural reading from prompt injection is an architectural problem: the vulnerability is not a defect in a component, it is the composition, a single channel carrying two trust levels.
What the leaked prompt bought the attacker
The leak is often dismissed as cosmetic, and it is not. The system prompt disclosed the internal policy thresholds, which lets an attacker craft requests that land just inside them. It disclosed the tool names and their parameters, which maps the action surface for further injection aimed at the tools. And it disclosed the refusal conventions, which trains the next attempt to route around them. The leaked prompt is reconnaissance, and the incident should be handled as such, per the reachability thinking in your dependency audit found ninety four issues and zero problems, where the question is what the disclosed information makes reachable.
The boundaries that were enforceable, and were missing
The postmortem found four controls that would have changed the outcome, none of which require the model to resist the instruction.
The assistant's output never needed the system prompt to be repeatable. A filter that treats the system prompt text as a secret and scans outgoing answers for it, refusing or redacting on overlap, is a data loss control at the egress, the same discipline as treating logs as an export in the pull request that logged an email address. The model may be persuaded to speak, but the egress does not have to transmit.
The tools were callable on the model's say so. The bot could invoke refund and account tools with no confirmation channel independent of the conversation, so an injected instruction had the same reach as a legitimate one. The fix is the classic confused deputy control: tools that mutate state require a confirmation out of band, or a capability token scoped to the authenticated user's intent, so the model's belief is never sufficient authority.
Retrieved content and user text shared one channel. The policy chunks, which are data, and the system instruction were interleaved, so data that mimics instruction is indistinguishable by position. Delimiting retrieved data with explicit, consistently formatted markers and instructing the model that marked content is data reduces the attack surface, imperfectly but measurably, and the markers are the closest thing to parameterisation the medium offers.
The sensitive policy did not need to be in the prompt. The thresholds lived in the prompt because that was convenient, but they could have lived in a policy service the bot queries with structured calls, returning only the decision, never the rule text. Moving the secret out of the context removes it from the set of things the model can repeat, which is removal, the only perfect redaction.
The testing that catches it
The injection suite is the security version of the eval harness: a corpus of injection attempts, naive and adaptive, run against every prompt version in CI, per treat a prompt change like a deploy, with the egress filter and the tool gates in the loop, because the controls are part of the system under test. The suite asserts not that the model refuses, which is probabilistic, but that the secret never leaves, which is the egress control's job and is deterministic. That split, probabilistic model behaviour checked statistically and deterministic controls checked exactly, is the architecture that survives.
If it happens again
A prompt is one channel carrying instruction and data, so the model's judgement is the only in band boundary, and it is adversarially attackable. Put the enforceable boundaries out of band: egress filters that treat the prompt as a secret, tool gates that require authority independent of the conversation, marked delimiters for retrieved data, and removal of anything sensitive from the context entirely.
The model can be persuaded. The egress, the gates and the vault cannot, and those are the three you are allowed to trust.