Bidi Text Attack
Exploiting Unicode bidirectional control characters to disguise malicious code or filenames. The 'Trojan Source' attack (CVE-2021-42574) uses bidi overrides to hide backdoors in source code.
What is a Bidirectional Text Attack?
A bidirectional text attack (also called a Bidi attack or Trojan Source attack) exploits the Unicode Bidirectional Algorithm (UBA) to make text appear to have different content than it actually contains. Because developers, reviewers, and administrators read text through rendering engines that apply the Bidi algorithm, they may see a safe-looking string while the underlying bytes contain something entirely different.
The Unicode Bidirectional Algorithm
The Unicode Bidirectional Algorithm (UAX#9) allows a single string to contain mixed left-to-right and right-to-left text — for example, an English sentence with an embedded Arabic phrase. It achieves this through invisible control characters that shift the rendering direction. The key control characters include:
- RLO (U+202E) — Right-to-Left Override: forces all following characters to render right-to-left
- LRO (U+202D) — Left-to-Right Override: forces left-to-right rendering
- RLE (U+202B) — Right-to-Left Embedding
- PDF (U+202C) — Pop Directional Formatting (ends an override or embedding)
- RLI (U+2067), LRI (U+2066), FSI (U+2068) — isolate variants (safer)
- PDI (U+2069) — Pop Directional Isolate
Trojan Source — CVE-2021-42574
In November 2021, researchers Nicholas Boucher and Ross Anderson published Trojan Source, demonstrating how Bidi control characters can be used to inject malicious code into source files in a way that is invisible during code review but interpreted differently by the compiler.
The classic Trojan Source example uses a comment to hide a string that contains an early string terminator and malicious logic:
// The attack (conceptual — do not copy literally into editors)
// access_level = "user\u202E \u2066// Check if admin\u2069 \u2066"
// What the compiler sees: access_level = "user" // followed by active code
// What reviewers see (rendered): access_level = "user // Check if admin"
The RLO and isolate characters cause the code review tool to reverse the display of a portion of the string, making the comment appear to close before the malicious content but actually not doing so in the source bytes.
RLO-Based Filename Disguise
Long before Trojan Source, attackers used U+202E (RLO) to disguise executable file extensions in filenames. A file named:
Invoice_[U+202E]gpj.exe
is displayed by Windows Explorer as Invoice_exe.jpg — the extension appears to be .jpg because RLO reverses the display of the characters after the control character. Users double-clicking the "image" run the .exe file.
GitHub and GitLab Mitigations
Following the Trojan Source disclosure, major code hosting platforms introduced countermeasures:
- GitHub added a warning banner on any file view that contains Bidi override or embedding characters, stating "This file contains bidirectional Unicode text that may be interpreted differently than what appears below."
- GitLab implemented similar warnings in the diff view and file viewer.
- gcc and clang compilers added warnings for Bidi control characters in string literals and comments.
- CVE-2021-42574 was issued and patched in multiple compilers and editors.
Defense Strategies
- Lint for Bidi control characters — add a pre-commit hook or CI check that rejects files containing U+202A–U+202E, U+2066–U+2069
- Configure editors — VS Code, JetBrains IDEs, and Vim can be configured to render Bidi control characters visibly
- Audit existing code — search codebases for the hex byte sequences:
E2 80 AAthroughE2 80 AE(UTF-8 for U+202A–U+202E)
Quick Facts
| Property | Value |
|---|---|
| CVE | CVE-2021-42574 (Trojan Source) |
| Researchers | Nicholas Boucher and Ross Anderson, Cambridge |
| Publication date | November 2021 |
| Key control chars | U+202E (RLO), U+202D (LRO), U+202B (RLE) |
| Attack surfaces | Source code review, filenames, web content, emails |
| Compiler mitigations | gcc -Wbidi-chars, clang warning added |
| Platform mitigations | GitHub/GitLab Bidi warning banners |
| Unicode standard | UAX#9 — Unicode Bidirectional Algorithm |
관련 용어
보안의 더 많은 용어
도메인 이름에 시각적으로 유사한 유니코드 문자를 사용하여 합법적인 사이트를 사칭하는 공격. аpple.com(키릴 …
Exploiting Unicode normalization to bypass security filters. Input validated before normalization may …
U+200D. 인접 문자의 결합을 요청합니다. 이모지 시퀀스에 필수적입니다(👩+ZWJ+💻=👩💻). 인도 문자에서는 합자 형성을 …
U+200C. 인접 문자의 결합을 방지합니다. 페르시아어/아랍어에서 올바른 글자 형태를 위해 필수적이며, 데바나가리에서 …
서로 다른 문자 체계에서 동일하거나 매우 유사하게 보이는 문자. 예: 라틴 'a'와 …
유니코드 양방향 재정의 문자(U+202A~U+202E, U+2066~U+2069)를 사용하여 악성 파일 이름이나 코드를 위장하는 공격. …
유니코드 기능을 사용하여 사용자를 속이는 것: 가짜 도메인을 위한 동형이자, 가짜 파일 …
confusables.txt(UCD)에 정의된 시각적으로 혼동될 수 있는 문자 쌍에 대한 유니코드 공식 용어. …
서로 다른 문자 체계의 문자를 혼합하는 텍스트를 식별합니다(예: 라틴 + 키릴). 동형이자 …