Prompt Injection Is a Code Review Problem, Not Just a Model Problem

Most teams shipping an LLM agent today have a SQL injection checklist for their API layer and nothing equivalent for the prompt layer. That gap is the whole problem: prompt injection isn’t a model weakness you patch by swapping providers, it’s an input-validation defect in your code, and it shows up in predictable places if you know where to look.
Where it actually lives
Prompt injection findings in a real review cluster around three spots:
- Untrusted content concatenated into the system or tool-result context. A support ticket body, a scraped web page, or a file the agent just read: anything an attacker can influence that lands in the context window without being clearly delimited from instructions.
- Tool definitions with no permission boundary. If the model can call a tool that deletes data, sends email, or hits an internal API, the question isn’t “would the model choose to do that”? It’s “what happens when injected text tells it to.“
- Multi-agent handoffs. An orchestrator that passes a sub-agent’s raw output to another sub-agent (or back to a tool) without re-validating it is a confused-deputy chain, not a single trust boundary.
A minimal review pattern
Example: unsafe Python-style context assembly
This is simplified Python-style application code, not a snippet from a specific AI SDK. It represents the kind of helper function an LLM agent might use to combine a user request and documents retrieved from a knowledge base before sending them to a model. The highlighted problem is that the retrieved documents are treated as trusted instructions.
def build_context(user_input: str, retrieved_docs: list[str]) -> str:
# BAD: retrieved_docs are concatenated as if they were trusted
return f"{SYSTEM_PROMPT}\n\n{user_input}\n\n" + "\n".join(retrieved_docs)
The fix isn’t a smarter prompt. It’s the same boundary discipline as any other injection class: label untrusted spans explicitly, strip or refuse content that mimics instruction syntax, and scope tool permissions so that even a fully “successful” injection can’t reach anything destructive.
What to bring to the next review
If your team already runs security review on pull requests, the checklist to add is short: where does untrusted text enter the context, what can the model call as a result, and what’s the blast radius if it calls the wrong thing on purpose. That’s the same question application security has asked for twenty years, but it has a new place to be asked.