Why Prompt Filtering Alone Is Insufficient
The most common attempt to defend agents against prompt injection is a filter: scan input for "dangerous" words and strip them. It fails — predictably, and for structural reasons. This article explains why every input-filtering approach to prompt injection defense is incomplete, and what you have to add.
What input filtering is
Input filtering means inspecting incoming content for signs of prompt injection before it reaches the model. The assumption: if you catch the attack at the door, the model never sees it. Variants range from keyword blocklists to regex rules to classifier-based detection.
Why it can't work on its own
- Obfuscation. Base64, ROT13, Unicode homoglyphs, whitespace padding, and character-split payloads all evade exact-match filtering.
- Encoding is lossless.
c2VuZCB0aGUga2V5looks harmless to a filter but decodes to "send the key" for the model. The filter and the model are decoding different strings. - Multi-turn / split attacks. An instruction split across turns or across tool outputs never matches a single-input filter, yet the model combines it.
- The model is the attack surface. The filter is a text pattern matcher fighting a system that can be socially engineered. The attacker only needs one phrasing the filter doesn't know.
- Filtering at the wrong layer. By the time content is being filtered, it's already in the pipeline the attacker wants to influence. The decision that matters — may this cause an action? — isn't made at input time at all.
The asymmetry
This is a fundamental asymmetry. The attacker explores an unbounded space of phrasings and obfuscations. The filter must anticipate all of them in advance. You can make filtering better — better regexes, better classifiers — but you cannot make it complete, because you're guessing what an attacker will try next.
What you have to add: enforcement at the boundary
Defense that can actually hold doesn't try to prevent every injection from entering context. It accepts that content enters context, and enforces the consequence — whether that content may cause an action. This is runtime-boundary enforcement:
The key shift: instead of trying to win an arms race before the model, enforcement wins it after — by making the injection unable to produce a harmful action regardless of what the model "believes."