Onderzoekers van de Universiteit van Cambridge hebben een techniek gepubliceerd voor het onopvallend injecteren van kwaadaardige code in peer-reviewed broncode. De ontwikkelde aanvalsmethode (CVE-2021-42574) staat bekend als Trojan Source en is gebaseerd op het creëren van tekst die er anders uitziet voor de compiler/interpreter en voor een mens die de code bekijkt. Voorbeelden van de toepassing van de methode zijn gedemonstreerd voor verschillende compilers en interpreters voor de talen C, C++ (gcc en clang), C#, JavaScript (Node.js), Java (OpenJDK 16), Rust, Go en Python.
De methode is gebaseerd op het gebruik van speciale Unicode-tekens in de codecommentaar, die de volgorde van de weergave van bidirectionele tekst veranderen. Met behulp van dergelijke controle-tekens kunnen sommige tekstgedeelten van links naar rechts en andere van rechts naar links worden weergegeven. In de dagelijkse praktijk kunnen dergelijke controle-tekens bijvoorbeeld worden gebruikt om regels in een codebestand in het Hebreeuws of Arabisch in te voegen. Maar als je regels met verschillende tekstrichtingen in één regel combineert met behulp van de genoemde tekens, kunnen delen van de tekst die van rechts naar links worden weergegeven de gewone tekst die van links naar rechts verschijnt, overlappen.
Door deze methode kan er een kwaadaardige constructie aan de code worden toegevoegd, maar de tekst met deze constructie kan onopvallend worden gemaakt bij het bekijken van de code, door het toevoegen van symbolen die van rechts naar links worden getoond in de daaropvolgende commentaar of binnen een literal, wat zal leiden tot het overlappen van de kwaadaardige invoeging met volledig andere symbolen. Dergelijke code blijft semantisch correct, maar zal anders worden geïnterpreteerd en weergegeven.

Tijdens het code-reviewproces zal de ontwikkelaar worden geconfronteerd met de visuele volgorde van de weergegeven symbolen en ziet hij een onverdacht commentaar in een moderne teksteditor, webinterface of IDE, terwijl de compiler en interpreter de logische volgorde van de symbolen gebruiken en de kwaadaardige invoeging behandelen zoals deze is, zonder aandacht te besteden aan de bidirectionele tekst in het commentaar. Verschillende populaire code-editors (VS Code, Emacs, Atom) en interfaces voor het bekijken van code in repositories (GitHub, GitLab, BitBucket en alle producten van Atlassian) zijn kwetsbaar voor dit probleem.

Er zijn verschillende manieren om de methode te gebruiken voor het uitvoeren van kwaadwillige acties: het toevoegen van een verborgen 'return'-uitdrukking, waardoor de uitvoering van de functie vroegtijdig wordt beëindigd; het commentariëren van uitdrukkingen die normaal zichtbaar zouden zijn als werkende constructies (bijvoorbeeld om belangrijke controles uit te schakelen); het toewijzen van andere tekenreeksen die leiden tot mislukkingen van controles op tekenreeksen.
Bijvoorbeeld, de aanvaller kan een wijziging voorstellen die de volgende regel bevat: if access_level != «user{U+202E} {U+2066} // Controleer of admin{U+2069} {U+2066}» {
deze zal in de interface voor beoordeling worden weergegeven als if access_level != «user» { // Controleer of admin
Daarnaast is er nog een andere aanvalsvector voorgesteld (CVE-2021-42694) die verband houdt met het gebruik van homoglieven, symbolen die visueel op elkaar lijken, maar verschillen in betekenis en verschillende Unicode-codes hebben (bijvoorbeeld, het symbool «ɑ» lijkt op «a», «ɡ» op «g», «ɩ» op «l»). Dergelijke symbolen kunnen in sommige talen worden gebruikt in functienamen en variabelen om ontwikkelaars in de war te brengen. Bijvoorbeeld, er kunnen twee functies worden gedefinieerd met ononderscheidbare namen die verschillende acties uitvoeren. Zonder gedetailleerde analyse is het niet duidelijk welke van deze twee functies op een bepaalde plaats wordt aangeroepen.

Als maatregel voor bescherming wordt aangeraden om in compilers, interpreters en buildtools die Unicode-symbolen ondersteunen, een fout of waarschuwing te genereren wanneer er in opmerkingen, stringliteralen of identificatoren oneven controlekarakters aanwezig zijn die de uitvoerrichting wijzigen (U+202A, U+202B, U+202C, U+202D, U+202E, U+2066, U+2067, U+2068, U+2069, U+061C, U+200E en U+200F). Dergelijke symbolen moeten ook expliciet worden verboden in de specificaties van programmeertalen en moeten worden overwogen in code-editors en interfaces voor het werken met repositories.
Aanvulling 1: Correcties ter verwijdering van de kwetsbaarheid zijn voorbereid voor GCC, LLVM/Clang, Rust, Go, Python en binutils. Het probleem is ook opgelost door GitHub, Bitbucket en Jira. Er wordt momenteel gewerkt aan een oplossing voor GitLab. Voor het identificeren van problematische code wordt voorgesteld om het volgende commando te gebruiken: grep -r $'[\u061C\u200E\u200F\u202A\u202B\u202C\u202D\u202E\u2066\u2067\u2068\u2069]’ /path/to/source
Aanvulling 2: Russ Cox, een van de ontwikkelaars van het besturingssysteem Plan 9 en de programmeertaal Go, bekritiseerde de overmatige aandacht voor de beschreven aanvalsmethode, die al lang bekend is (Go, Rust, C++, Ruby) en niet serieus werd genomen. Volgens Cox betreft het probleem voornamelijk de correctheid van de weergave van informatie in code-editors en webinterfaces, wat kan worden opgelost door het gebruik van de juiste tools en code-analyzers tijdens het reviewproces. Daarom zou het, in plaats van aandacht te besteden aan theoretische aanvallen, beter zijn om de focus te leggen op het verbeteren van de processen voor code- en dependency-review.
Russ Cox is van mening dat compilers niet de juiste plek zijn om het probleem aan te pakken, omdat, door gevaarlijke symbolen op compilatieniveau te verbieden, er nog steeds een enorme laag aan tools blijft waar het gebruik van deze symbolen is toegestaan, zoals buildsystemen, assemblers, package managers en diverse parsers voor configuratie en data. Ter illustratie wordt het Rust-project genoemd, dat de verwerking van LTR/RTL-code in de compiler verbood, maar geen correctie toevoegde aan de package manager Cargo, waardoor een soortgelijke aanval via een Cargo.toml-bestand mogelijk blijft. Evenzo kunnen aanvallen worden gestart vanuit bestanden zoals BUILD.bazel, CMakefile, Cargo.toml, Dockerfile, GNUmakefile, Makefile, go.mod, package.json, pom.xml en requirements.txt.
Bron: opennet.ru
