Tokenization and filter bypass
A moderation filter that scans for a banned word is checking the wrong layer. The model never sees words — it sees tokens, and the mapping between the two is easy to disturb.
By Piotr Zenon Żabrowski · Published · Updated
The filter checks strings, the model reads tokens
Tokenization splits input text into vocabulary units before anything else happens — a whole word, a fragment, punctuation, or a single character, depending on how the tokenizer's algorithm (commonly Byte Pair Encoding) merged character pairs during training. A word-matching filter checks the raw string. Tokenization itself is deterministic: identical characters, through the same tokenizer and pipeline, always produce the same token sequence. What breaks a filter is that two inputs which look identical to a human are not always the same characters underneath — a lookalike code point, an inserted formatting character, or a different script can sit behind text that reads the same on screen, and each variant tokenizes on its own terms.
What manipulation changes the outcome
- Unusual spacing or inserted characters (zero-width characters, extra punctuation) push a word's split point somewhere the filter's pattern doesn't anticipate.
- Homoglyphs, full-width Unicode variants, and mixed scripts substitute different code points for characters that render the same way, so the visible word survives but the token sequence behind it does not match what the filter was written to catch.
- Switching to a language the moderation layer was tuned less carefully for changes the tokenization and the coverage a security team can vouch for.
A second, quieter cost: tokenization is not language-neutral
Token count depends on how well a tokenizer's learned vocabulary fits a language's morphology, not on meaning alone. If the training corpus behind the merge rules is mostly English, the vocabulary ends up with whole-word entries for common English forms, while heavily inflected languages get cut into smaller subword pieces to cover endings the vocabulary never learned as single units. Two sentences with the same meaning and word count can land at different token counts once tokenized. That is not a filter bypass, but a budgeting problem: usage-based pricing charges per token on input and output regardless of answer quality, and a context window or rate limit sized on English-language testing leaves less real headroom for text that tokenizes less efficiently.
What holds up
Design for tokens, not strings
- Run moderation on model output and on normalized, decoded text — not just the raw pre-tokenization string.
- Normalize Unicode (NFKC) before any string-based filter runs, and handle zero-width and control characters through an explicit, language-aware policy rather than stripping them all — some are load-bearing in scripts using joiners or combining marks. Test the policy against real multilingual samples before rollout.
- Treat keyword and regex filters as a noise reducer, not a security boundary — pair them with a classifier that scores meaning, not surface form.
- Track per-language token cost separately when budgeting or rate-limiting; a flat per-request token cap is not language-neutral.
Frequently asked questions
Does an invisible edit to a string really change what the model reads?
Only if it changes what's actually there. Tokenization is deterministic for a given input and tokenizer — feed it the same code points twice and it splits them the same way twice. What an attacker changes is the input itself: swapping in a homoglyph, a full-width character, or a zero-width joiner produces a string that looks the same on screen but is a different sequence of code points, and that different sequence tokenizes differently. The filter and the model can end up disagreeing about what was said because they were, technically, shown different text.
Is Unicode normalization enough to stop these bypasses?
It closes the cheapest version of the trick, not the category. Normalization should run before any string-based check, but treat it as one layer, not the fix — the underlying issue is that a filter matches strings while the model reasons over tokens, which means output-side and meaning-based checks still matter more than input pattern-matching.
Related
AI security
How to secure GenAI, LLM and agentic AI systems: current OWASP threat classes, layered controls, agent authority, retrieval isolation and monitoring.
Context window structure
Why mixing data and instructions in the same context window causes prompt injection, and how 'lost in the middle' behavior degrades operational security.
AI security assessment
Security assessment of GenAI and LLM systems: prompt injection, tool and agent abuse, data leakage, model supply chain and monitoring gaps.
STRIDE for AI systems
Applying STRIDE to LLM and agentic applications: what each category means when untrusted text can act as instructions, where STRIDE stops covering multi-agent failure modes, and the controls per element.
Prompt injection defence
Why prompt injection cannot be filtered away, why it has no full fix yet, and how to design AI systems — architecturally, not just with better prompts — so a successful injection has no useful consequence.
LLM security controls
A control checklist for enterprise GenAI: data handling, retrieval isolation, agent authority, cascading-failure containment, monitoring, cost limits and vendor terms.