What is the Trojan Source attack?
Trojan Source is a technique for making source code compile or execute differently from how it appears to a human reader. Nicholas Boucher and Ross Anderson of the University of Cambridge published the technique on November 1, 2021, showing that Unicode bidirectional (BiDi) control characters — the same characters covered on this site's BiDi character remover page — can be placed inside a comment or string literal to visually reorder the code around them, without changing what the compiler actually reads byte-for-byte.
The underlying cause is the Unicode Bidirectional Algorithm, built so a line can mix left-to-right scripts like English with right-to-left scripts like Arabic or Hebrew and still display in the correct reading order. Source-code parsers were never designed to guard against that same mechanism being used adversarially, so an override character such as U+202E (right-to-left override) can make a stretch of source display in reverse order on screen while the compiler still processes it left to right, byte by byte.
How "Early Return" and "Commenting-Out" work
The paper names two concrete exploitation patterns. In Early Return, an attacker hides a functional return statement inside what looks like an inert comment or string; because BiDi controls only affect display order, not the underlying byte sequence, the compiler still executes the hidden statement and the function exits before the code the reviewer sees ever runs. In Commenting-Out, the trick runs in reverse: BiDi characters make a live line of code — a permission check or an input validation, for example — display as though it sits safely inside a comment, so a reviewer reads past it as dead text while it keeps executing normally.
Both patterns rely on the same small set of invisible characters: U+202A–U+202E (the embedding and override controls) and the newer isolate controls U+2066–U+2069. None of them have a visible glyph of their own — they only change how the characters around them are drawn — which is exactly what makes them invisible in a normal code review.
CVE-2021-42574, CVE-2021-42694, and who it affects
The disclosure carries two CVE identifiers. CVE-2021-42574 covers the BiDi override technique described above. A second, related identifier, CVE-2021-42694, covers a separate technique from the same paper that swaps identifiers for visually near-identical homoglyphs instead of reordering them — the same family of substitution covered in more depth on the homoglyph attack detection page. Because dozens of compiler vendors, language maintainers, and code-hosting platforms received the report under coordinated disclosure before the public date, both CVEs are cited broadly across advisories rather than tied to one specific product.
| Language tested | Result in the paper |
|---|---|
| C / C++ | Vulnerable — both techniques compiled and ran as hidden |
| C# | Vulnerable |
| JavaScript | Vulnerable |
| Java | Vulnerable |
| Rust | Vulnerable |
| Go | Vulnerable |
| Python | Vulnerable |
The authors noted the root cause sits in how source files are parsed relative to the Unicode Bidirectional Algorithm, not in any one compiler's bug — so any language accepting UTF-8 or UTF-16 source with BiDi characters allowed inside comments or strings is a plausible candidate, not only the eight tested.
How GitHub and editors catch it today
GitHub shipped detection the same day the vulnerability went public: since October 31, 2021, any file or pull-request diff containing bidirectional Unicode control characters gets a visible warning banner, prompting a reviewer to inspect the raw bytes before approving. The banner is informational only — it does not block a merge on its own — so a reviewer still has to click through and act on it. Editors add a second layer: Visual Studio Code highlights BiDi control characters inline by default, and dedicated scanners such as the researchers' own reference detector can be run in CI to fail a build outright rather than just warn.
Checking a snippet before it goes in a commit
Most Trojan Source characters don't arrive through a targeted attack — they ride along in code copied from a chat assistant, a forum post, a PDF, or a webpage that mixed scripts somewhere upstream, the same way tag-character smuggling and stray BiDi marks do. Paste a snippet into the hidden character checker above to see every directional control character by code point and count without changing anything, or run it through the BiDi character remover to strip them outright before it reaches version control. For code, JSON, and CSV generally, see sanitizing copied text for code, JSON, and CSV.