Hiding Vulnerabilities in Source Code
Ross Anderson (via Bruce Schneier):
Today we are releasing Trojan Source: Invisible Vulnerabilities, a paper describing cool new tricks for crafting targeted vulnerabilities that are invisible to human code reviewers.
Until now, an adversary wanting to smuggle a vulnerability into software could try inserting an unobtrusive bug in an obscure piece of code. Critical open-source projects such as operating systems depend on human review of all new code to detect malicious contributions by volunteers. So how might wicked code evade human eyes?
We have discovered ways of manipulating the encoding of source code files so that human viewers and compilers see different logic. One particularly pernicious method uses Unicode directionality override characters to display code as an anagram of its true logic.
Previously:
- Hiding Data in Emoji
- A Vatican-Sized Flag Mystery
- Unicode and Copying and Pasting Code
- Fingerprinting Swift Code Using Spacecrypt
1 Comment RSS · Twitter · Mastodon
Since this was published in 2021 I think various compilers were updated to detect it. For example compiling the sample Rust source now yields the following:
error: unicode codepoint changing visible direction of text present in literal
--> /tmp/test.rs:3:24
|
3 | if access_level != "user� �// Check if admin� �" {
| ^^^^^-^-^^^^^^^^^^^^^^^^^-^-^
| | | | | |
| | | | | '\u{2066}'
| | | | '\u{2069}'
| | | '\u{2066}'
| | '\u{202e}'
| this literal contains invisible unicode text flow control codepoints
|
= note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
= note: `#[deny(text_direction_codepoint_in_literal)]` on by default
= help: if their presence wasn't intentional, you can remove them
help: if you want to keep them but make them visible in your source code, you can escape them
|
3 | if access_level != "user\u{202e} \u{2066}// Check if admin\u{2069} \u{2066}" {
| ~~~~~~~~ ~~~~~~~~ ~~~~~~~~ ~~~~~~~~
error: aborting due to 1 previous error