Researchers from the University of Cambridge have published a technique for invisibly injecting malicious code into reviewed source texts. The prepared attack method (CVE-2021-42574), known as Trojan Source, is based on creating text that looks different to the compiler/interpreter than to a human reading the code. Examples of this method have been demonstrated for various compilers and interpreters supplied for the C, C++ (gcc and clang), C#, JavaScript (Node.js), Java (OpenJDK 16), Rust, Go, and Python languages.
The method relies on the use of special Unicode characters in code comments that change the display order of bidirectional text. With such control characters, some parts of the text can be displayed left-to-right while others can be displayed right-to-left. In practice, such control characters can be used to insert lines in Hebrew or Arabic into a code file. However, if strings with different text directions are combined within a single line, these characters can cause portions of text displayed right-to-left to overlap existing standard text displayed left-to-right.
By using this method, a malicious construct can be added to the code, but then make the text containing this construct invisible when viewing the code, by adding characters shown right-to-left in a subsequent comment or within a literal. This results in completely different characters overlaying the malicious insertion. Such code will remain semantically correct, but will be interpreted and displayed differently.

During the code review process, the developer will encounter a visual output order of characters and will see an innocuous-looking comment in modern text editors, web interfaces, or IDEs. However, the compiler and interpreter will use the logical order of characters and process the malicious insertion as is, ignoring the bidirectional text in the comment. Various popular code editors (VS Code, Emacs, Atom) and code viewing interfaces in repositories (GitHub, GitLab, BitBucket, and all Atlassian products) are susceptible to this issue.

Several methods of using the technique for malicious actions are highlighted: adding a hidden expression 'return' that leads to premature function termination; commenting out expressions normally visible as active constructs (for example, to disable important checks); assigning other string values that cause string validation failures.
For example, an attacker might suggest a modification that includes the line: if access_level != 'user{U+202E} {U+2066}// Check if admin{U+2069} {U+2066}' {
which will be displayed in the review interface as if access_level != 'user' { // Check if admin
Additionally, another attack variant (CVE-2021-42694) has been proposed, related to the use of homoglyphs, symbols that look similar in shape but differ in meaning and have different unicode codes (for example, the character 'ɑ' resembles 'a', 'ɡ' resembles 'g', 'ɩ' resembles 'l'). Such symbols can be used in some languages in function and variable names to mislead developers. For instance, two functions with indistinguishable names can be defined that perform different actions. Without detailed examination, it is not immediately clear which of these two functions is being called in a specific instance.

As a protective measure, it is recommended to implement error or warning outputs in compilers, interpreters, and build tools that support Unicode characters when there are unpaired control characters in comments, string literals, or identifiers that alter output direction (U+202A, U+202B, U+202C, U+202D, U+202E, U+2066, U+2067, U+2068, U+2069, U+061C, U+200E, and U+200F). Such characters should also be explicitly prohibited in programming language specifications and should be taken into account in code editors and interfaces for working with repositories.
Appendix 1: Fixes addressing the vulnerability have been prepared for GCC, LLVM/Clang, Rust, Go, Python, and binutils. The issue has also been addressed by GitHub, Bitbucket, and Jira. A fix for GitLab is currently in preparation. To identify problematic code, it is suggested to use the command: grep -r $'[\u061C\u200E\u200F\u202A\u202B\u202C\u202D\u202E\u2066\u2067\u2068\u2069]' /path/to/source
Addendum 2: Russ Cox, one of the developers of the Plan 9 OS and the Go programming language, criticized the excessive attention given to the described attack method, which has long been known (Go, Rust, C++, Ruby) and was not taken seriously. According to Cox, the issue mainly concerns the accuracy of information display in code editors and web interfaces, which can be addressed by using proper tools and code analyzers during reviews. Therefore, instead of drawing attention to theoretical attacks, it would be more appropriate to focus on improving the processes of code and dependency reviews.
Russ Cox also believes that compilers are not the right place to address the issue, as banning dangerous characters at the compiler level leaves a vast array of tools where the use of these characters remains permissible, such as build systems, assemblers, package managers, and various configuration and data parsers. For instance, the Rust project banned the processing of LTR/RTL code in the compiler but did not add a fix in the Cargo package manager, allowing similar attacks through the Cargo.toml file. Similarly, sources of attacks can be files like BUILD.bazel, CMakefile, Cargo.toml, Dockerfile, GNUmakefile, Makefile, go.mod, package.json, pom.xml, and requirements.txt.
Source: opennet.ru
