Token Smuggling / Unicode Injection (LLM01:2025)

SkillAI & models

Detects user input passed to LLMs without Unicode normalization, allowing RTL

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Token Smuggling / Unicode Injection (LLM01:2025) skill

What this skill tells your AI

The instructions your AI receives, as published by thejefflarson/soundcheck in .claude/skills/token-smuggling/SKILL.md and read by ahel’s review.

What this checks

Detects user input passed to LLMs without Unicode normalization. Attackers embed RTL override characters, zero-width joiners, or homoglyphs to manipulate prompt structure, bypass keyword filters, or make malicious instructions appear legitimate.

Vulnerable patterns

  • User input interpolated into a prompt with no normalization step at the trust boundary
  • Blocklists or keyword filters that compare against pre-normalized text, letting homoglyph variants pass
  • Retrieved RAG content or tool outputs concatenated into a prompt on a path the sanitizer does not cover
  • Comparisons on raw bytes where bidirectional overrides or zero-width characters can split or hide tokens

Fix immediately

Flag the vulnerable code, explain the risk, and suggest a fix establishing these properties. Translate to the Unicode library or runtime APIs of the audited file — use that stack's documented NFKC normalization and character-class predicates; do not import a recipe from a different stack.

  1. User input is NFKC-normalized before it reaches any prompt or blocklist comparison. NFKC collapses compatibility forms and canonical equivalents, so homoglyphs, fullwidth digits, and ligatures fold to their ASCII counterparts. Normalization runs once, at the trust boundary — not scattered per call site.
  2. Unicode control and invisible formatting characters are stripped after normalization. Bidirectional overrides (U+202AU+202E), zero-width space/joiner (U+200BU+200D), word joiner (U+2060), and BOM (U+FEFF) do not survive into the prompt. These are the characters attackers use to hide instructions or split keywords.
  3. Security-sensitive comparisons (blocklists, keyword filters, domain allowlists) run on normalized input, not on the raw bytes. A filter that checks for a string but runs on pre-normalized text lets the homoglyph variant pass.
  4. The same helper runs on every ingress path — direct user input, retrieved RAG content, tool outputs. Attackers move the payload wherever the sanitizer does not run.

Verification

  • User input is normalized with NFKC before inclusion in any LLM prompt
  • Unicode control and invisible formatting characters are stripped before prompt construction
  • Security-sensitive string comparisons (blocklists, keyword filters) run on normalized input
  • All ingress paths — direct input, retrieved content, tool outputs — pass through the same sanitization helper

References

Signals

GitHub stars
20
Last commit
Jul 2026
Advanced
Catalog kind
skill
Gateway key
token-smuggling
Source
github.com/thejefflarson/soundcheck