Istraživači sa Sveučilišta Cambridge objavili su tehniku nevidljive zamjene zlonamjernog koda u recenziranim izvorima. Pripremljena metoda napada (CVE-2021-42574) predstavljena je pod imenom Trojan Source i temelji se na stvaranju teksta koji izgleda drugačije za kompajler/interpretator i za osobu koja gleda kod. Primjeri primjene metode prikazani su za različite kompajlere i interpretatore koji se koriste za jezike C, C++ (gcc i clang), C#, JavaScript (Node.js), Java (OpenJDK 16), Rust, Go i Python.
Metoda se zasniva na korištenju posebnih Unicode simbola u komentarima koda koji mijenjaju redoslijed prikazivanja dvosmjernog teksta. Pomoću takvih kontrolnih simbola neki dijelovi teksta mogu se prikazivati slijeva nadesno, a drugi zdesna nalijevo. U svakodnevnoj praksi, takvi kontrolni simboli mogu se koristiti, na primjer, za umetanje linija na hebrejskom ili arapskom jeziku u datoteku s kodom. No, ako se kombinuju linije s različitim smjerovima teksta u jednoj liniji, uz pomoć navedenih simbola, dijelovi teksta koji se prikazuju zdesna nalijevo mogu preklapati već postojeći uobičajeni tekst koji se prikazuje slijeva nadesno.
Korištenjem ove metode u kod se može dodati zlonamjerna konstrukcija, ali potom učiniti tekst s tom konstrukcijom neprimjetnim prilikom pregleda koda, dodavanjem u istoj sljedećoj komentaru ili unutar literalnih simbola koji se prikazuju zdesna nalijevo, što će dovesti do preklapanja zlonamjernog umetanja posve drugih simbola. Takav kod ostat će semantički ispravan, ali će se različito interpretirati i prikazivati.

Tijekom recenziranja koda, programer će se suočiti s vizualnim redoslijedom prikaza simbola i vidjeti u modernom tekstualnom uredu, web sučelju ili IDE-u ne sumnjiv komentar, ali će kompajler i interpretator koristi logički redoslijed simbola i obraditi zlonamjerno umetanje onako kako jest, ne obraćajući pažnju na dvosmjerni tekst u komentarima. Problem su podložni razni popularni uređivači koda (VS Code, Emacs, Atom), kao i sučelja za pregled koda u repozitorijima (GitHub, Gitlab, BitBucket i svi proizvodi Atlassiana).

Izpostavljeni so različni načini uporabe metode za izvajanje zlonamernih dejanj: dodajanje skritega izraza "return", ki povzroči predčasno končanje izvajanja funkcije; zaklocking v komentar izraze, ki so normalno vidni kot veljavne konstrukcije (na primer za onemogočanje pomembnih preverjanj); dodeljevanje drugih nizov, kar povzroči napake pri preverjanju nizov.
Na primer, napadalec lahko predlaga spremembo, ki vključuje vrstico: if access_level != "user{U+202E} {U+2066}// Check if admin{U+2069} {U+2066}" {
ki bo prikazana v vmesniku za pregled kot if access_level != "user" { // Check if admin
Dodatno je bil predlagan še en način napada (CVE-2021-42694), povezan z uporabo homoglifov, znakov, ki izgledajo podobni, vendar se razlikujejo po pomenu in imajo različne unicode kode (na primer, znak "ɑ" spominja na "a", "ɡ" na "g", "ɩ" na "l"). Takšni znaki se lahko uporabljajo v nekaterih jezikh za imena funkcij in spremenljivk, da zmedejo razvijalce. Na primer, lahko sta definirani dve funkciji z nerazločljivimi imeni, ki izvajata različne naloge. Brez podrobnega pregleda takoj ni mogoče razumeti, katera od teh dveh funkcij se kliče na določenem mestu.

Kot ukrep za zaščito se priporoča implementacija v prevajalnikih, interpreterjih in orodjih za gradnjo, ki podpirajo Unicode znake, za izhod napake ali opozorila ob prisotnosti neparnih kontrolnih znakov, ki spreminjajo smer izhoda (U+202A, U+202B, U+202C, U+202D, U+202E, U+2066, U+2067, U+2068, U+2069, U+061C, U+200E in U+200F) v komentarjih, nizovnih literali ali identifikatorjih. Takšni znaki bi morali biti tudi izrecno prepovedani v specifikacijah programskih jezikov in bi morali biti upoštevani v urejevalnikih kode in vmesnikih za delo z repozitoriji.
Dodatek 1: Popravki za odpravo ranljivosti so bili pripravljeni za GCC, LLVM/Clang, Rust, Go, Python in binutils. Problematiko so prav tako odpravili GitHub, Bitbucket in Jira. V teku je priprava rešitve za GitLab. Za identifikacijo problematične kode je predlagano, da se uporabi ukaz: grep -r $'[\u061C\u200E\u200F\u202A\u202B\u202C\u202D\u202E\u2066\u2067\u2068\u2069]' /path/to/source
Dopolnjenje 2: Russ Cox, eden od razvijalcev operacijskega sistema Plan 9 in programskega jezika Go, je kritiziral pretirano pozornost do opisanega napada, ki je že dolgo znan (Go, Rust, C++, Ruby) in ni bil obravnavan resno. Po Coxovem mnenju se problem predvsem nanaša na pravilno prikazovanje informacij v urejevalnikih kode in spletnih vmesnikih, kar se reši z uporabo ustreznih orodij in analizatorjev kode pri pregledovanju. Zato bi bilo bolje, namesto da pritegnemo pozornost k teoretičnim napadom, osredotočiti se na izboljšanje procesov pregledovanja kode in odvisnosti.
Russ Cox prav tako meni, da compilerji niso pravo mesto za reševanje težave, saj je prepoved nevarnih simbolov na ravni compilerja le del težave, saj ostaja ogromno orodij, v katerih je uporaba teh simbolov še vedno sprejemljiva, kot so sistemi za sestavljanje, assemblerji, upravljalniki paketov in različni parserji konfiguracije in podatkov. Na primer, projekt Rust je prepovedal obravnavo LTR/RLT kode v compilerju, a ni dodal popravka v upravljalnik paketov Cargo, kar omogoča podoben napad preko datoteke Cargo.toml. Podobno lahko napadalci izkoristijo datoteke, kot so BUILD.bazel, CMakefile, Cargo.toml, Dockerfile, GNUmakefile, Makefile, go.mod, package.json, pom.xml in requirements.txt.
Izvor: opennet.ru
