Bidirectional Text Attacks: How Unicode Spoofing Works
In late 2021, security researchers disclosed Trojan Source—a class of attack that uses Unicode bidirectional control characters to make source code appear different to a human reviewer than it does to a compiler. The attack is subtle, difficult to detect visually, and affects virtually every programming language and code-review tool. Here's how it works and how to defend against it.
The Bidirectional Override Characters
Unicode includes several bidirectional embedding and override characters that change how text is rendered visually without affecting the underlying code points. The most dangerous for source code is U+202E RIGHT-TO-LEFT OVERRIDE (RLO), which causes all subsequent characters on the line to display in reverse order until cancelled by U+202C POP DIRECTIONAL FORMATTING (PDF).
An attacker can embed these control characters inside a comment or string literal. The compiler ignores them (they're valid Unicode), but a code review tool or text editor renders the surrounding text in a different visual order—effectively hiding malicious code that the compiler executes.
The Trojan Source Attack in Practice
Consider a comment in C code that appears to show // Check if admin to a reviewer but actually contains a closing */ sequence that ends a block comment earlier than it appears, exposing executable code that was hidden in what looked like a comment. The bidi characters cause the visual display to reorder characters, making the dangerous sequence invisible in review.
Defences
- Compiler and linter warnings: GCC, Clang, and Rust now warn on bidirectional control characters in source code. Enable these warnings.
- Code review tools: Platforms like GitHub have added alerts for bidi characters in diffs. Check that yours does too.
- Editor plugins: Several VS Code extensions highlight invisible Unicode control characters in source files.
- Input sanitisation: Strip or reject bidirectional control characters in user-supplied content wherever they serve no legitimate purpose.
The bidi control characters are closely related to the zero-width characters covered in more detail on the zero-width characters page. The confusable characters article covers the complementary homograph attack vector.