24 ms·
‘Trojan Source’ Bug Threatens the Security of All Code
- mmastrac 5y agoFun story: I discovered these in the early 2000s and simultaneously discovered that Slashdot didn't filter these out. I spent an evening randomly reversing large sections of comment pages until they finally blocked it. I'm very, very sorry CmdrTaco.
- kingcharles 5y agoMost web sites' comment sections will allow these. I think even Facebook allows tomfoolery like this. f̷̧̨̡̜͚̬̰͕̩̻̳̜̮̫̰̓̏̑̐̇̍͘͝è̶̙̥͚̰͈͚̹̜̼͙͚͌à̴̛̙̣̖̮̰̥̩͚̣̺͋̂̓̓̍͛͜ͅr̶̛͎̬̭̯͙͉̬̞̤̲̞̼͉̣̃̒͗̄̎̋͆̓̊͐͝ͅ ̷̦̬̳̹̦̳̭͓͖͔̺̮̩̓̆̍̊͆͊͜ẗ̵̩͙̼́̂̿́̂̈́̈́̑ḩ̸̨̝͇̖̤̱̠̼̣͈̩͈̰̃̂͂͋̏̇͗͛̓̈́̍̑͑̕̚͜ë̶̥̜̘͙̦̋ ̸̛̟̀̄̌͗́̄ͅų̷̪͙̰̜̟̰̦͇̞̥̜͓͇͊̆͗̆̀͗̀̈́̌̉͆̏͆͜ṫ̸̨̜͈̲̺͖͓̄̍̄̓̏̓̓̎͜ͅf̴̨̼̜̯͇̜̯̹͚͛8̴̧̤͖̠̳̜̤̻̟̏̀̽̃m̷̯̤̳͔̘̣͙̗̰͙͔̦̰̝͑͐͌̓̎̀̇̓̆͂̎̐̽̚͠ą̶̢̻͂̒͛̑̅̈͛͑̈́̓̚͠͝n̴̦̺͖̆̑͗̾̈̀̉̿̑̐̈́͝ͅͅ
- scatters 5y agoWell yes, Facebook has users in Vietnam. Stacked diacritics are a features, not a bug.
- Cthulhu_ 5y agoI've seen some sites / services (Discord?) filter these out, at least to the point where they don't escape a message's vertical space. I'm sure they're truncated because those messages are pretty big in terms of amount of bytes. And while they have valid use cases, I can't see it in e.g. comment sections or chat messages. Happy to have someone link to e.g. a Vietnamese comment section showing practical use though.
- Timwi 5y agoVietnamese Wikipedia has plenty of Talk pages with discussion threads.
- cmdrtaco 5y agoI’m sure you created a shitty day for one of us :( I’d like to say this was unusual, but it was pretty common.
- mmastrac 5y agoOof. :( My bad, definitely sorry. A case of your favourite bubbly pop on me.
- edent 5y agoBDI can be used to evade profanity filters. Writing something like `‮kcuf` will display a banned word. Does it work here? > I am an toidi No? HN strips the BDI. But there are plenty of other systems which display weird RTL behavior.
- lokedhs 5y agoYes, Mastodon has recently been discussing this. https://github.com/mastodon/mastodon/issues/2777 https://github.com/mastodon/mastodon/issues/2777
- zeepzeep 5y agoThe good old SexyHexe.pdf strikes again. These problems won't go away for a while, unicode is fucking hard. Almost every app I ever tried it had at least some problems with %u202E (the right to left overwrite),
- akersten 5y agoIt is wrong to call this a bug, this is a feature of Unicode and very intentional. Whether we should have thought about that when allowing parsers to digest anything outside of ASCII is the real question. The answer is probably "IDEs and compilers should ignore character-direction codes when looking at source files." But that doesn't solve homoglyph attacks (and other undiscovered deception). What a fun can of worms. Who gets to solve it?
- kingcharles 5y agoYou're right - their headline is written for attention. It's an exploit of a feature. What I'm interested to know is whether there is any code already out there in the wild with this exploit in it? An intelligence service could have exploited this years ago without anyone noticing until now. Unicode is a pathway to all manner of hijinks, including as you say, homoglyph attacks. For instance, on some TLDs I can easily create two different domain names that render identically in the browser.
- comex 5y ago> What I'm interested to know is whether there is any code already out there in the wild with this exploit in it? It's possible, but I doubt it. The paper mentions that Vim isn't vulnerable to the bidirectional attack. Not mentioned in the paper: neither is `less`, the pager, which is used by default for `git diff` and other Git commands. Nor are either of the first two terminals I tried, when `cat`ing the file without a pager. All of the aforementioned programs display the direction markers as either escape sequences highlighted in bright colors, or garbage characters, both of which stand out visually like a sore thumb. Now, that's more a sign of poor Unicode support in those programs than it is anything to their credit. But it does mean that this kind of attack is incredibly brittle, at least in any codebase where some people working on it are likely to be using Unix tools. There's a high chance the aberrant characters will be spotted at some point or other. And once spotted, it's self-evident that it's an attack. I suspect real attacks would try to be more subtle, introducing bugs that could pass as genuine mistakes, at least at first glance.
- 5y ago
- Groxx 5y agoEhhhh... Interesting philosophically, and we might see a practical attack maybe eventually, but most source code editors and diff reviewers that I've encountered show all non-printable characters VERY visibly. Because they matter, and always have - "func asdf()" is very different from "func as<zwsp>df()". If I saw a pile of non-printable control characters intermixed in code in a diff, there's absolutely no way I'd allow that merge. IOCCC entries will absolutely become more fun though.
- lifthrasiir 5y ago> IOCCC entries will absolutely become more fun though. IOCCC doesn't allow unescaped octets with high bit set [1], so even that's no go. [1] https://www.ioccc.org/2020/rules.txt https://www.ioccc.org/2020/rules.txt (rule 13)
- Groxx 5y agoAww. But also of course they've already addressed this.
- saagarjha 5y agoI am very curious which program abused this and forced the creation of that rule.
- lifthrasiir 5y agoProbably 2000/briddlebane [1]. But it is more like a guard against compatibility issues. [1] https://www.ioccc.org/2000/briddlebane.c https://www.ioccc.org/2000/briddlebane.c vs. https://www.ioccc.org/2000/briddlebane.orig.c https://www.ioccc.org/2000/briddlebane.orig.c
- GlitchMr 5y agoWell, technically the rule only talks about entries that "fail to compile". An entry that still compiles is fine, see rule 12. In practice this means the Unicode abuse like this is only allowed in strings.
- simmo9000 5y agoHere is an example, open it in an appropriate editor (vi) and you can see how easy it is to 'exploit' (if you can call it that?). https://github.com/nickboucher/trojan-source/blob/main/JavaScript/stretched-string.js https://github.com/nickboucher/trojan-source/blob/main/JavaS... Seams like a layer 8 problem?
- brundolf 5y agoGitHub has already updated their UI I see
- techsolomon 5y agoChangelog – https://github.blog/changelog/2021-10-31-warning-about-bidirectional-unicode-text/ https://github.blog/changelog/2021-10-31-warning-about-bidir...
- Groxx 5y agoThe Android app renders it much more suspiciously too, though unfortunately no warning: https://imgur.com/a/L3sNFQ8 https://imgur.com/a/L3sNFQ8
- Semaphor 5y agoIn case there are people who (currently) don’t have access to such an editor, here is a screenshot: https://i.imgur.com/2Ue2Vvd.png https://i.imgur.com/2Ue2Vvd.png
- siddhesh 5y agoYou mean, like this? https://imgur.com/a/unKuOoK https://imgur.com/a/unKuOoK Snark aside, most text based editors have some giveaway or another. Even the GUI ones show syntax highlighting quirks that show that something is wrong. This is only really relevant in unicode-aware terminals, without syntax highlighting and when you don't get to scroll between characters. IOW, it's really quite hard to do.
- visarga 5y agoWhy is it called a Trojan horse instead of a Greek horse?
- panarky 5y agoBecause the Greeks transferred ownership.
- alanhaha 5y agoWill this also fool formatter? Actually I think the format of the example in https://www.trojansource.codes/ https://www.trojansource.codes/ is too strange that I would like committer to fix.
- kens 5y agoThis reminds me of a trick you could do on the Commodore PET in the 1980s, where you'd embed backspaces in your BASIC code. If someone looked at the code they'd see something different from what gets executed. Effective to keep someone from copying your code in class :-)
- josephcsible 5y agoWhy is bidirectionality handled when text is being rendered onto the screen, instead of when it's being input from the keyboard? Why not render every single character in LTR order, and have RTL support instead be handled by text input fields moving the cursor in the opposite direction after each RTL character is typed? (I know it's too late to change this now. I'm asking why we didn't do it this way from the beginning.)
- swiftcoder 5y agoIf you have a document with mixed languages, you need to be able to edit each language in its natural direction after the fact. That requires storing directionality in the document. And keep in mind that if you store RTL text backwards, as you propose, every algorithm now has to be able to process backwards text. Backwards spellcheck is a lot of extra work...
- deleted 5y ago[deleted]
- jart 5y agoIf I understand correctly, what you're suggesting could be thought of as pre-rendering directionality into the memory layout. If we did that then it might compromise our ability to write an algorithm that iterates over a string of hebrew or arabic characters. Display is super complicated and people don't agree on how to do it. For example, consider the arabic text عودة أبو تايه. If I sneak a latin A between all those characters to prevent the display algorithm from rearranging and shaping them, then that same string looks like this: عAوAدAةAأAبAوAتAاAيAه. Those are the same characters and you can confirm that yourself using: for c in 'عودة أبو تايه': print(unicodedata.name(c)) On the other hand if you want to romanize that string as EWDTA AEBW TAIH then all you need is a for loop and a switch statement, because the memory order is always left to right. We can also rest assured that if someone invents a better display algorithm, we won't need to do any database migrations, since the encoding itself doesn't need to change.
- laurowyn 5y agoBecause visual representation is separate from the underlying data structure. A string container doesn't have a specific direction, only a relative one. I.e. This character comes before the next and after the previous. Adding the bidi control code, the string indicates when the visual ordering changes in this relative direction system. You could absolutely design a new string container that assumes left to right at all times and cannot be changed, but then it's on the programmer to ensure that strings are copied or concatenated in the right direction, at the right location, and substrings searching becomes a minor headache. How would you concatenate an RTL string to a forced LTR string representation? You would have to work out whether the end of the string it LTR or RTL. If LTR, append directly. If RTL find the character where the direction changes and insert the string in there - much more expensive. Better to just append the string, using bidi codes where required, and let the frontend process the string to make the appropriate direction changes. Yes, you may need to search the string for the bidi code to know which direction you're going at the end of the string, but that's just a simple reverse string search for a single control character, and not a complex variable multi-byte search of inferred character directions by codepoint values. I think the issue is in the locations of which bidi codes are rendered. They provide an inherent untrustworthy-ness to the text area they're rendered in, and so should be treated as an exception in critical situations. I've seen the reversed exe file name trick used for years, and every time I ask myself why that's even a thing? If the OS used file headers and magic numbers to determine file types instead of the filename, it would be less of an issue. For source code, I would question the rendering of RTL text in a source code editor as it's an obvious issue for code safety. Ideally, all source code would be kept to the same origin language - doesn't have to be english, just consistent. Any non-conforming text should ideally be loaded from a resource rather than inline within the source code, to avoid foreign character contamination and allow easier identification of these issues. Further, source code rendering should only render identified safe control codes, and treat unsafe ones as raw binary values to be shown as such - i.e. \r and \n are safe, \b is unsafe, and bidi codes would also be unsafe. You could even go so far as to include them in the syntax highlighting, but that results in a dependency on syntax highlighting to show the semantics of the source code rather than the text alone.
- tannhaeuser 5y agoThat Unicode with its extremely large character set would become a solution to any and all character encoding problems in itself was never the case. Usually, for a given document you'll want to declare the subset that's actually in use such that a particular font with necessarily limited coverage can be used to render it. That's what's available for SGML markup documents eg in an SGML declaration, where you can declare and construct a document character set from planes or arbitrary code point ranges, and an SGML parser can verify actual content against that subset.
- froh 5y agoWas that capability dropped in the transition from sgml to XML? If so, can someone here on HN provide some pointers to the old discussion?
- tannhaeuser 5y agoAll discussion related to create XML as an SGML subset can be found on the xml-dev mailing list [1], with some earlier discussions and initial drafts of the SGML ERB mostly linked from there. The capability to declare document character sets was dropped along with supporting an SGML declaration altogether. [1]: http://lists.xml.org/archives/xml-dev/ http://lists.xml.org/archives/xml-dev/
- smsm42 5y ago> Cambridge research clearly shows that most compilers can be tricked with Unicode into processing code in a different way than a reader would expect it to be processed. Unless I misunderstand the premise, this in not right. The compiler is not "tricked" into doing anything different - it interprets the code the same way as it always did. It's like saying "rm" command "can be tricked into" deleting important files. The rm tool doesn't know which files are important to you, and the compiler doesn't - and shouldn't - know what you consider to be "correct" code. It would correctly compile any code that is syntactically correct - if there are strings inside that look weird to you, it doesn't matter to the compiler. The entity that can be "tricked" here is the reviewer of the code - who, indeed, might probably be tricked into accepting code that does something different than they'd think it does (though it'd require a very clever attacker to for the code to both do something nefarious with Unicode and still look innocent and not weird to the reviewer). Fortunately, this is quite easy to fix - just don't accept any patches with source code that have any non-ASCII outside small set of localization resources (proper code would have localizable resources outside the code anyway, tbh) and no Unicode would ever trick you.
- __alexs 5y ago> Fortunately, this is quite easy to fix - just don't accept any patches with source code that have any non-ASCII outside small set of localization resources There are plenty of projects out there written by people who aren't English speakers who depend on the Unicode capabilities of languages to write code that is actually readable to them. Turning that off is far from a solution.
- ivanhoe 5y agoDoes anyone actually do that in a production code? I myself am not native English speaker and use unicode when writing in my mother tongue, but in 20+ years of programming I've never seen anyone using non-ascii chars in their professionally written code? Of course, you use the language in localization files, and perhaps in comments occasionally - especially in TODO stuff that's not meant to be permanent - but not in the actual code, like e.g. for a variable or function names. I'd actually consider it a bad idea, as it limits significantly who can manage that code in the future.
- ComodoHacker 5y agoThe paper: https://www.trojansource.codes/trojan-source.pdf https://www.trojansource.codes/trojan-source.pdf
- jeroenhd 5y agoIt all depends on your IDE. I've tried this, and IntelliJ and friends will show a little block with the text RLO for the right to left override or ZWS for zero with spaces for any non-standard character that might mess things up. (Neo)vim will show the unicode espace sequence instead of rendering the text as unicode directs it. Some compilers, notably clang, will warn you that you're using an "invisible character". Assuming you at least read the warnings your code generates (because if you don't, why not just put exploitable algorithms deep down ontthe software?) you'd probably catch the issue. Simpler programs such as the text editor that ships with GNOME will freak out, but I don't think most people are coding in that in the first place. I think this is an interesting peculiarity, but it's not a "threat" to "the security of all code".
- aulin 5y agoI'd say that neovim is bugged here and gedit is the one working properly rendering unicode as it should be
- deleted 5y ago[deleted]
- aww_dang 5y agoI filed this domain away under 'security alarmist nonsense' years ago. This headline and story are prime examples of the form.
- sydthrowaway 5y agoSeriously. State run espionage is 100x more likely
- TruthWillHurt 5y agoIs this a real cause for concern? Simply don't copy code with strange unicode charecters, just like you don't copy code with blocks of bytecode.
- samus 5y agoIt's a problem in any environment where people can input Unicode characters. Reviewers might use tools that are not able to see those things. At the same time, one can't just put a blanket ban on Unicode. It exists for a reason. People want to use their native languages to name identifiers, or at least to write comments. Restricting ourselves to ASCII again and thus forcing English on everybody is not a solution.
- lixtra 5y ago> Restricting ourselves to ASCII again and thus forcing English on everybody is not a solution. Yet most programming languages force them to use English Arabic numbers. Wouldn’t it be great to use Roman numerals? And then images in source code are really difficult to handle. Wouldn’t it be nice to compile a word document with embedded images? I think I wouldn’t mind staying with ASCII for source code, except for string literals (difficult enough).
- samus 5y agoArabic numerals can be justified since they are dominant and most commonly used in modern science and technology across the whole world. Supporting additional systems would not introduce too much hassle though. Numbers follow a rigid syntax and generally do not employ free mixing with numerals from other systems. What I have in mind actually exists already: Jupyther notebooks, which combine code, text, and resources combined into a nice JSON ball. Horrible for SCMs and editors without using special plugins of course.
- mkl 5y agoThe point of the vulnerability is that you can't necessarily see the strange Unicode characters.
- pitdicker 5y agoSecurity advisory for the Rust programming language (with a nice explanation): https://blog.rust-lang.org/2021/11/01/cve-2021-42574.html https://blog.rust-lang.org/2021/11/01/cve-2021-42574.html Rust 1.56.1 will be released later today. > To assess the security of the ecosystem we analyzed all crate versions ever published on crates.io (as of 2021-10-17), and only 5 crates have the affected codepoints in their source code, with none of the occurrences being malicious. Preview of the new helpful error: https://i.imgur.com/pGpZOnr.png https://i.imgur.com/pGpZOnr.png
- robin_reala 5y agoThat’s a really impressively written error message.
- sodality2 5y agoThat's one of Rust's selling points. For all I've used the rust compiler, not once have I ever not known what error it was pointing out: its error messages are incredibly helpful. Occasionally I am unsure why it's an error, but I always know what it's referring to and what I could do to fix it.
- Timwi 5y agoI've had the same experience with C#. The error messages always state exactly what's wrong and where in the code it's wrong. Many of them (especially compiler _warnings_ intended to point out syntax that is almost certainly a bug) also tell you how to fix it (e.g. “consider using ‘new’ keyword if hiding was intended”).
- hermitdev 5y agoPersonally, I don't know why the last one (“consider using ‘new’ keyword if hiding was intended”) isn't an error by default in C# . Not overriding the base method is almost always a mistake, and if it's not a mistake, better to be explicit about it, anyways. My $.02...
- 5y ago
- littlestymaar 5y agoSomething puzzles me: this kind of tricks would definitely break syntax highlighting, wouldn't it?
- deleted 5y ago[deleted]
- jwilk 5y agoAnother HN discussion: https://news.ycombinator.com/item?id=29061987 https://news.ycombinator.com/item?id=29061987
- ChrisMarshallNY 5y agoLooks like avoiding dependencies and snippets is a good way to mitigate this. In my own work, I use almost no dependencies (aside from compilers and built-in APIs). Scratch that. I use a lot of dependencies, but ones that I have written, and generally rewrite snippets, when I use them. Also, very little of the code I see, has comments. Like, any comments; even headerdoc comments. > Green said the good news is that the researchers conducted a widespread vulnerability scan, but were unable to find evidence that anyone was exploiting this. Yet. … “yet” … I know that I’m a “dependency curmudgeon,” but stuff like this just serves to reinforce my posture.
- Cthulhu_ 5y agoBut what if this is slipped into your compiler? Your operating system's kernel? A top voted Stack Overflow answer? You can't (or it's infeasible to) check and control everything.
- _3u10 5y agoYes, you're totally safe then. I've never heard of standard libraries having problems that affect security, certainly not the str* family of functions.
- ChrisMarshallNY 5y agoAny particular reason for the nasty? I thought we didn't do that kind of thing, around these parts, but I'm often wrong.
- _3u10 5y agoThe pain of having worked under these conditions of not using libraries, usually having to work with subpar libraries that were developed internally. Like oh, hey, we need a database, great, lets roll our own. Or the ancient version of whatever lib shipped with the OS that is full of bugs solved in subsequent versions. I see that you now use a lot of dependencies, and retract my statement.
- z29LiTp5qUC30n 5y agoThe bootstrappable community already produced a solution for this: https://github.com/oriansj/stage0/blob/master/High_level_prototypes/sin.c https://github.com/oriansj/stage0/blob/master/High_level_pro...
- im3w1l 5y agoI remember bringing this up many years ago. Yes specifically making code seem like comments using bidi. I'm just a little bit salty I won't get the credit. https://bugs.eclipse.org/bugs/show_bug.cgi?id=339146 https://bugs.eclipse.org/bugs/show_bug.cgi?id=339146
- fullstackchris 5y agoI fail to see how this can actaully be used as an exploit. As some commenters have said, yes, it may be a risk to some open source tools where there is poor due diligence for merge request review process - but that is almost never the case. Otherwise, if you own your own code, this obviously isn't an issue. (Unless, of couse, for some reason you want to program exploits into software at your organization :) ) Heck, even GitHub already shows a warning for files that have bi-directional unicode... A bit of an overemotional title if you ask me.
- pietroalbini 5y agoIt's this research that prompted GitHub to show warnings, they didn't appear as of yesterday.
- willvarfar 5y agohttps://blog.rust-lang.org/2021/11/01/cve-2021-42574.html https://blog.rust-lang.org/2021/11/01/cve-2021-42574.html has a nice clear example. Full Stack Chris reviews some code that he thinks says: if access_level != "user" { // Check if admin This may be an open source project. This may be an internal bad egg (a very common threat; insider jobs are actually one of the absolute top risks to a company). Or this code may be injected by an attacker who has gained access to the repo and is leaving backdoors that they hope to survive long after their access is blocked or leaving backdoors to make deployed production systems vulnerable. Etc. And Chris won't notice that the computer will execute: if access_level != "user{U+202E} {U+2066}// Check if admin{U+2069} {U+2066}" { This is not just an attack on compiled languages. Scripting languages are just as vulnerable.
- kiklion 5y agoSorry, still don’t get it. Isn’t the issue that they are using magic strings? If the strings were something like RoleConstants.Admin then this is avoided? Though I don’t understand the point of the Unicode characters in the comment string so I must be missing something.
- 5y ago
- robotmay 5y agoThis was a pretty interesting thing to mitigate - we added some support around it to GitLab after it was reported to us, which shipped in the latest security release: https://gitlab.com/gitlab-org/gitlab/-/commit/3fb44197195b5789b99a13f7bf482e9a895dfc58 https://gitlab.com/gitlab-org/gitlab/-/commit/3fb44197195b57... (you can actually see it in effect on that commit's examples, which is quite meta). These characters have valid use-cases in right-to-left languages like Arabic, Japanese etc, so it had to be configurable for project-owners if they have legitimate use-cases for it. Our focus was on making sure that repository maintainers could see these characters in code reviews. The homoglyph attack is interesting but it really should be noticed as part of a code review process, as it requires adding the imitation function calls at some point too. It'd also likely be pretty frustrating to end users if we were to highlight every single unicode character that looks like the latin alphabet. It's certainly a good lesson in not copy/pasting random snippets from the internet and pasting them into a root shell, however :D (we do always highlight the bidi characters on GitLab snippets, though) Aside: this was a royal pain in the arse to figure out if I had live examples in the specs, because vim also just rendered them "correctly". I ended up checking the files in Windows Notepad on another machine to sanity check them. Thanks to the authors for responsible disclosure.
- jhgb 5y ago> It'd also likely be pretty frustrating to end users if we were to highlight every single unicode character that looks like the latin alphabet. That actually strikes me as very desirable. (Especially in light of the old maxim that "programs must be written for people to read, and only incidentally for machines to execute".)
- wizzwizz4 5y agoThose Unicode characters aren't just there for show. They're part of real scripts that real people use; it would be annoying for people using those scripts.
- jhgb 5y agoI'm fairly sure this could be arranged for. As in, if there's too many of them belonging to the character set of a particular language, then it's very likely that it's simply a text in that language. But random characters in the middle of ASCII identifiers are probably not something that you want.
- qwerty456127 5y agoDespite I'm not a native English speaker and I meant almost all the programs I ever wrote to be capable of processing any given language (and also have localized UIs in some cases), I see no reason for non-English strings to be allowed in source code and code files except some ad-hoc scripts in which hard-coding some text can be an optimal solution. We probably just need a git switch which would make it throw an error if it encounters Bidi or any weirdness like that except in resource files.
- mkl 5y agoNon-English characters are quite useful in comments where you're explaining Unicode processing stuff, and in regexes working with the characters, and when you're using maths notation (proper symbols in comments, Greek letters for variables, etc.), and when you're drawing boxes in a terminal. I'm sure there are many more too.
- qwerty456127 5y agoI omitted this to keep it simple (this is why I wrote non-English rather than non-ASCII, I actually am a proponent of active usage of proper Unicode symbols like ⇒, ≠, etc, and also TUIs) but yes, I would prefer a rather extended English char-set including Greek letters, mathematical symbols, pseudographics etc. These can be useful and are not much trickier than English letters. But I would certainly like to see at least a warning (I would even prefer an Error actually) if my code file includes anything related to RTL, complex character composition or non-Latin letters other than Greek.
- samus 5y agoSince most progamming languages are based on english, non-english text in string literals is almost always user-facing and should be put in resource files to make translation into additional languages easier. Identifiers and comments are a serious problem though. Many application domains use terms that are tricky to translate into english. The translations could be misleading, inappropriate or not unique. Sometimes they are just plain wrong or there is no english word that fits. All of these could cause misconceptions, confusion and bugs, and make reading and working with the code and the running system harder.
- samus 5y agoIt's maybe worth to make a step back and take a new look at the underlying problem. Source code combines multiple kinds of text. There are * hierarchical structure, * mathematical and logical syntax * literals (especially insidious: text) * free text in comments and * markup in documentation These newly discovered vulnerabilities remind me of the issue of SQL injection, which is also caused by a confusion when combining these kinds of text. For SQL injection, the solution was to introduce facilities to explicitly combine SQL syntax and dynamic literals. Maybe we need something similar for code that enforces such strict separation. Maybe into different files or nested into a container format. There are already facilities for doing so (resource files, templating languages) but they are opt-in and don't go far enough to address the newly discovered problems. The cost would be that code could become more difficult to edit with plain-text editors.
- metroholografix 5y agoEmacs "fix": (setq bidi-display-reordering nil) in relevant modes.
- perihelions 5y agoI forced it globally, are there reasons that's bad to do? (setf (default-value 'bidi-display-reordering) nil) The BIDI issue looks pretty bad in emacs-gtk: the sneaky text is unnoticeable in lots of modes, unless the cursor just happens to scroll over it.
- josephcsible 5y agoWhy did you put "fix" in quotes? Isn't that an actual fix for this?
- dathinab 5y agoI would say less that they discovered a new vulnerability but they they but needed focus on a long term known problem. It's just that many people while knowing the problem never considered that it could be used in supply chain attacks.
- dwheeler 5y agoAs I previously noted on a related post: Interesting paper. Note, however, that the general problem is already known and there are a number of pre-existing works that discuss it. This is typically called "underhanded code" or sometimes "maliciously misleading code". I'm surprised that they didn't use the normal term for the problem nor cite the previous work on it - maybe they didn't realize this was a widely-known problem? Previous works on underhanded code didn't discuss Bidi to my knowledge (though other attacks on text like this have exploited Bidi). Here are a number of other materials about underhanded code: The Obfuscated V Contest (http://graphics.stanford.edu/~danielh/vote/vote.html http://graphics.stanford.edu/~danielh/vote/vote.html) was created by Daniel Horn in 2004 and is the earliest “underhanded” programming contest that I found. It was a contest to create source code that looked like it did one thing, but actually did another. Underhanded C Contest (http://www.underhanded-c.org/ http://www.underhanded-c.org/) has run in many years. Per its FAQ, "The Underhanded C Contest is an annual contest to write innocent-looking C code implementing malicious behavior." My PhD dissertation "Fully Countering Trusting Trust through Diverse Double-Compiling" discusses how to counter the "trusting trust" problem & includes a section about maliciously misleading source code. See: https://dwheeler.com/trusting-trust/ https://dwheeler.com/trusting-trust/ The JavaScript Misdirection Contest announced the winner on September 27, 2015 http://misdirect.ion.land/ http://misdirect.ion.land/ My paper "Initial Analysis of Underhanded Source Code", (by David A. Wheeler, April, 2020, IDA document: D-13166), discusses underhanded code and the effectiveness of several potential countermeasures. It also includes a number of citations to other works on underhanded code. https://www.ida.org/research-and-publications/publications/all/i/in/initial-analysis-of-underhanded-source-code https://www.ida.org/research-and-publications/publications/a...
- kfichter 5y agoFirst place winner of last year's underhanded Solidity contest used exactly this trick: https://blog.soliditylang.org/2020/12/03/solidity-underhanded-contest-winners/ https://blog.soliditylang.org/2020/12/03/solidity-underhande...
- axic 5y agoThere was related issue in 2018 regarding line endings, which would allow disguised some lines as code, but keeping them as comments: https://docs.google.com/document/d/1PZBSCBWBwd6AqWCgXqLnw8FNQ4HRurP5usrXuKuU0a0/edit#heading=h.y1dslkvhlt7h https://docs.google.com/document/d/1PZBSCBWBwd6AqWCgXqLnw8FN... Both of these were fixed in Solidity shortly after the bug reports. (P.S. I'm a member of the Solidity team)
- afrcnc 5y agoDuplicate: https://news.ycombinator.com/item?id=29061987 https://news.ycombinator.com/item?id=29061987
- pweezy 5y agoIt’s not the same thing, but brings to mind Ken Thomason’s famous “Reflections on Trusting Trust” [0] from 1984. That describes a concept, over several stages, where a compiler can be made to change the behavior of programs it compiles in a difficult-to-find way. [0]: https://www.cs.cmu.edu/~rdriley/487/papers/Thompson_1984_ReflectionsonTrustingTrust.pdf https://www.cs.cmu.edu/~rdriley/487/papers/Thompson_1984_Ref...
- sqs 5y agoCode search is helpful to see if any of your code contains these characters. A bunch of hits found across the top ~2M open-source repositories: https://sourcegraph.com/search?q=context:global+%5Cx%7B202A%7D%7C%5Cx%7B202B%7D%7C%5Cx%7B202D%7D%7C%5Cx%7B202E%7D%7C%5Cx%7B2066%7D%7C%5Cx%7B2067%7D%7C%5Cx%7B2068%7D%7C%5Cx%7B202C%7D%7C%5Cx%7B2069%7D&patternType=regexp https://sourcegraph.com/search?q=context:global+%5Cx%7B202A%... To triage, you probably want to first look at hits in code files (not JSON or Markdown, etc.): https://sourcegraph.com/search?q=context:global+%5Cx%7B202A%7D%7C%5Cx%7B202B%7D%7C%5Cx%7B202D%7D%7C%5Cx%7B202E%7D%7C%5Cx%7B2066%7D%7C%5Cx%7B2067%7D%7C%5Cx%7B2068%7D%7C%5Cx%7B202C%7D%7C%5Cx%7B2069%7D+-lang:json+-lang:markdown+-lang:text&patternType=regexp https://sourcegraph.com/search?q=context:global+%5Cx%7B202A%... You can set up a self-hosted instance of Sourcegraph to run this across all of your company's code: https://docs.sourcegraph.com/ https://docs.sourcegraph.com/.
- TacticalCoder 5y agoHonest question: would it be that bad to mandate and enforce 100% ASCII source files? Arguably every and any Unicode character and, well, arguably even any string of characters can (should?) go to a properties/resources file (properties/resources files which, btw, also greatly simplifies i18n/l10n). Then build/commit/test hooks could be used to enforce that source code files are indeed 100% ASCII. I know, I know... Some are going to lament they don't have their shiny Unicode symbols right in their source file. But... It looks like you get what you pay for. Bruce Schneier wrote it when Unicode came out btw: "Unicode is too complex to ever be secure".
- dotancohen 5y agoThough I comment source in English, lots of people that I work with comment in other languages. כולל עברית, מימין לשמאל.
- EamonnMR 5y agoHaving readable unicode in string literals is nice.
- Jeff_Brown 5y ago> Bruce Schneier wrote it when Unicode came out btw: "Unicode is too complex to ever be secure". It's astounding to me that there's room for such complexity in it. I thought it was just a lot of symbols. What other rules does Unicode have besides changing the order sometimes?
- ncc-erik 5y agoThe one a lot of folks know about was the soft hyphen (U+00AD) to bypass swear filters. I was able to use normalization to create XSS attacks.
- supperburg 5y agoHow dare you suggest something sensible. The mob will soon be knocking at your door.
- sfgweilr4f 5y ago
- Pxtl 5y agoI skimmed the article but I didn't see any examples of this being exploited... Has anybody done a proof of concept on how Bidi can be used? I'm having trouble thinking of a line of code with a comment or literal where the code is legit forwards but malicious backwards.
- sqs 5y agoThis issue has been raised before, such as at https://github.com/golang/go/issues/20209 https://github.com/golang/go/issues/20209 (I was reminded of that by https://twitter.com/peter_szilagyi/status/1455150803472297988 https://twitter.com/peter_szilagyi/status/145515080347229798...). There is some other interesting discussion there.
- pabs3 5y agoAre there any linters that detect these sorts of issues?
- marcodiego 5y agoI thought this was a case of Source code virus[1]. With the current popularity of open source and services like github, combined with deep inter-dependencies in node.js, a virus of this kind could have a huge impact if unnoticed for long enough. Maybe it is the next plague waiting to happen? [1] https://en.wikipedia.org/wiki/Source_code_virus https://en.wikipedia.org/wiki/Source_code_virus
- mwcampbell 5y ago> So you can use them in source code that appears innocuous to a human reviewer To a sighted human reviewer. If I'm not mistaken, a blind programmer using a screen reader would be immune to this trick.
- brazzy 5y agoIf the screen reader understands Bidi (which it needs to in order to support some languages), maybe not.
- throw10920 5y agoOr, hear me out - instead of trying to work around a legitimate feature of Unicode, you could stop storing your source code as text, because it isn't. Code is not text - it's a tree of objects, and representing it as a flat sequence of text characters causes many problems and inefficiencies (including this one!) that could be mitigated if you just stored and manipulated it as a tree. The only reason why text was justifiable as a storage and manipulation format for code in the first place was because early computers (probably?) couldn't handle a tree format. That excuse has been invalid for several decades now, as is the idea that "everything is plain text". Code isn't plain text - if it was, then you could make arbitrary edits without syntax errors, but you can't, because code has structure. Start treating it that way.
- shaunxcode 5y agoYes! This would also do away with a whole class of conflicts related to whitespace/formatting.
- throw10920 5y agoExactly! Imagine a version control system where you get diffs on the AST tree, instead of the characters that make up the source (add an `if` and suddenly dozens of lines have "changed"), or the tabs/spaces flamewar evaporating instantly.
- account42 5y agoNothing is stopping your current version control tool from parsing the code and showing a structural difff now.
- rocqua 5y agoThe thing about text is that it is barebones. Everyone can agree what the structure of text is (a stream of bytes with some ascii like encoding). For representing code as more than text, you will lose so much tools that can handle your code, it's a massive set back. Add to that how much effort it takes to get people onboarded on your new representation, and things look bleak for adoption. Finally, programmers really like looking under the hood. And with plain text, you know exactly what your code looks like in bytes.
- a-dub 5y agowasn't there something a while back where people were triggering buffer overflows in terminal emulators with malicious (and invisible to the pretty printed eye) escape codes?
- ziml77 5y agoWould the solution to this be to render the direction switch control character similar to how some text editors will render 0 bytes as a glyph with the text NUL? You could still render everything after it with the reversed direction, but it provides a visible indicator that it's been done. It might be a little annoying for people who use RTL languages, but it seems like the benefit may outweigh that.
- pdonis 5y agoThis article talks about compilers, but what about interpreted languages like Python or Lisp?
- banana_giraffe 5y agoFor anyone that wants to see the real code: https://gist.github.com/Q726kbXuN/3c978a63cb6de5168c017da4df0d6bd3 https://gist.github.com/Q726kbXuN/3c978a63cb6de5168c017da4df... I've not seen one editor yet that doesn't at least hint there's a problem with syntax highlighting, if not just outright show nonsense.
- SavantIdiot 5y agoThis exploit requires comments. I think most code is safe.
- user2994cb 5y agoI'm sure there are some creative uses in C-style comments for U+2215, Division Slash: ∕
- WalterBright 5y agoHomoglyphs are a disaster and should never have been admitted into Unicode. There should never have been invisible semantic information embedded in Unicode.
- Gunax 5y agoI am still confused. Is the text not visible? If I write some text in a comment, it should still be visibe, regardless of direction/bidi code, right?
- Too 5y agoIs there any pre-commit check one can use to totally block this in my repo? Others might have legitimate use case for this but I certainly don’t, we keep localization in known file types only.
- db48x 5y agoA pre–commit hook is just a script that returns 0 to allow the commit. If you want to block commits containing certain characters, just make a hook that runs grep -v with a suitable search expression.