
Photo: perspec_photo88 (BY-SA)
AI & AgentsPrompt Injection Is the New SQL Injection — Without the Fix
SQL injection worked because a system could not distinguish the instructions a developer wrote from the data a user supplied. Both arrived as one string, and the interpreter executed whatever it read. We spent two decades learning to separate them, and parameterised queries eventually made the problem tractable.
Prompt injection is the same failure, and at present we have no equivalent fix.
The shape of the problem
A language model receives one stream of tokens. Your system prompt, the user’s request, and any content the model retrieves — a web page, an email, a document, a code comment — arrive in that same stream. The model has no reliable mechanism for treating some of those tokens as trusted instructions and others as untrusted data.
So if a summarisation agent fetches a page containing text that reads like an instruction, that text competes for the model’s attention with your own instructions. Sometimes it wins.
The reason this is worse than it sounds is that the injected content does not need to reach a human. An agent that reads a document, decides to call a tool, and acts on the result can be redirected without anyone seeing the text that redirected it.
Why the obvious defences do not hold
Telling the model to ignore instructions in content is a request, not a control. It raises the difficulty and does not establish a boundary. Any defence phrased as an instruction can be argued with by another instruction.
Delimiters and tagging help marginally and are not a boundary either. The model is still reading one stream; the tags are tokens like any other.
Input filtering assumes injection looks like something. It does not have to. It can be phrased as ordinary prose, encoded, translated, or split across sources, and the filter has to catch every variation while the attacker needs one.
A second model checking the first inherits the same weakness, because the checker also cannot separate instruction from data.
What actually reduces the risk
The defences that work are architectural, and they all assume the injection succeeds.
Constrain what tools can do, not what the model may say. If an agent has a read-only database credential, a successful injection cannot delete anything. Least privilege applied to tools is worth more than any amount of prompt engineering.
Separate the trust levels of tools and content. An agent that has read untrusted content should not then be permitted to call high-consequence tools in the same session. This is inconvenient and it is the single most effective structural control available.
Confirm irreversible actions with a human. Sending, paying, deleting, publishing — these should require a person to approve the specific action, with the actual parameters visible. Not a blanket approval at session start.
Log tool calls, not just conversations. The record you need after an incident is which tools were invoked with which arguments. Transcripts alone will not tell you what happened.
The uncomfortable position
Parameterised queries solved SQL injection by making a real separation between code and data at the interface. No equivalent exists for language models, because the flexibility that makes them useful is precisely their willingness to treat any text as potentially instructive.
Until that changes, the correct posture is to assume any agent processing untrusted content can be induced to misbehave, and to build so that misbehaviour is bounded. That is an unsatisfying answer. It is also the one that survives contact with an adversary.
Get new posts by email
Occasional writing on post-quantum cryptography, blockchain security and digital forensics. No more than twice a month, and nothing else.


