Rust e memory-safe, nu supply-chain-safe: cazul arrayref
de Claudiu Hulea · IT Management Consultant
Rust îți dă memorie sigură. Nu îți dă și un lanț de aprovizionare sigur. Pe 20 august 2026, trei crate-uri Rust populare au fost otrăvite ca să livreze un infostealer, iar memory safety nu a avut nimic de spus în această poveste. Atacul a rulat cod pe mașina dezvoltatorului la compilare, prin exact mecanismul pe care ecosistemul îl consideră normal.
Cel mai descărcat dintre ele, arrayref, are 245 de milioane de descărcări. În aval sunt biblioteci ca blake3 și framework-uri GUI (egui, eframe, iced), plus componente din Ethereum și Solana.
Pe scurt
- Crate-uri otrăvite:
arrayref(0.3.10),append-only-vec(0.1.9),internment(0.8.7), toate de la același cont de mentainer, compromis prin preluare de cont. - Metoda: codul upstream a rămas neatins. Atacatorul a injectat o dependență pe
proc-macro1, un typosquat al foarte popularuluiproc-macro2. - Payload: un infostealer care rulează la compilare, prin
build.rs. Multi-platformă (Windows, Linux, macOS), fură credențiale din Chrome, Brave și Edge, își face persistență și vorbește cu un server de comandă. - Scara:
arrayrefare 245 de milioane de descărcări totale, 53 de milioane în ultimele 90 de zile. În aval:blake3,egui,eframe,iced, componente Ethereum și Solana. - Reacție: fereastra de expunere a fost de circa două ore. Atribuire: infrastructura se suprapune cu campanii nord-coreene (Mastra, axios).
- Descoperit de: StepSecurity, Wiz, SafeDep, Aikido.
Cum a funcționat
Atacul nu a spart nimic în sens clasic. A folosit încrederea.
Întâi, preluarea contului. Atacatorul a creat conturi false de GitHub și crates.io care impersonau un dezvoltator cunoscut (David Tolnay) și a obținut controlul asupra publicării celor trei crate-uri. Codul lor a rămas identic cu cel legitim, ca să nu ridice suspiciuni la o citire rapidă.
Apoi, typosquat-ul. Singura schimbare vizibilă a fost o dependență nouă: proc-macro1, cu un nume la o cifră distanță de proc-macro2, unul dintre cele mai folosite crate-uri din tot ecosistemul. Într-un arbore de sute de dependențe tranzitive, un nume „aproape corect” trece neobservat.
proc-macro1 conținea un script build.rs, care se execută automat la compilare. El reconstruia infrastructura din fragmente codificate base64 și alegea payload-ul potrivit sistemului de operare (Windows, Linux, macOS pe x86_64 și ARM64). Apoi pornea un infostealer: credențiale din bazele SQLite ale browserelor Chrome, Brave și Edge, persistență prin Registry, LaunchAgent și systemd, plus comunicare cu un server de comandă.
De ce build.rs schimbă totul
Aici e miezul, și partea care nu are legătură cu Rust în particular. Codul malițios nu rulează când pornești aplicația. Rulează când o compilezi.
build.rs e un mecanism legitim: multe crate-uri îl folosesc ca să genereze cod, să detecteze capabilități sau să lege biblioteci native. Dar înseamnă că un simplu cargo build execută cod terț, pe stația dezvoltatorului sau pe runner-ul de CI, cu drepturile utilizatorului care compilează. E un nivel pe care antivirusul și EDR-ul de endpoint rareori îl monitorizează, fiindcă „un build care rulează un build script” arată perfect normal.
E același tipar ca la npm, cu postinstall, și ca la typosquat-ul obug/piccolore din ecosistemul JavaScript: execuție la instalare sau la build, sub radar. Rust nu e o excepție de la clasa asta. E doar mai nou pe lista țintelor.
De ce memory safety nu te salvează
Rust elimină o categorie întreagă de vulnerabilități: buffer overflow, use-after-free, data races. Sunt reale și valoroase. Dar sunt bug-uri în codul pe care îl scrii tu.
Atacul de supply chain nu exploatează un bug. Exploatează încrederea în ce tragi. Un build.rs malițios rulează cu toate drepturile pe care i le dă compilarea, indiferent cât de memory-safe e restul programului. Garanția limbajului se oprește la codul pe care îl controlezi, iar dependența ostilă e deja înăuntru, invitată.
De aceea „scriem în Rust, deci suntem în siguranță” e o propoziție incompletă. Rust rezolvă o problemă. Lanțul de aprovizionare e alta, și se apără cu alte controale.
Ce oprește acest atac
Vestea bună: exact acest atac se oprește cu igiena de supply chain care contează oricum. Niciunul dintre controalele de mai jos nu e exotic.
cargo denype surse și avize. O politică ce interzice orice registru sau sursă neașteptată și verifică arborele față de baza de avize (RustSec) prinde o dependență nouă, necunoscută, cum eproc-macro1. Rulat în CI, ca poartă care oprește build-ul.- Vendoring și build offline. Dacă dependențele sunt vendorizate și build-ul rulează fără acces la rețea, o versiune nou-publicată și malițioasă nu poate fi trasă automat. Construiești din ce ai revizuit, nu din ce s-a publicat azi.
- Pinning cu
Cargo.lock. Fixează versiuni exacte și tratează orice modificare a arborelui de dependențe ca schimbare de cod, revizuită în PR.arrayref@0.3.10nu ajunge în build dacă lock-file-ul e pinat pe o versiune curată. - CI izolat. Runner-ele care compilează execută cod terț prin
build.rs. Limitează-le accesul la rețea și la secrete, și rotește periodic credențialele accesibile din mediul de build. - Mai puține dependențe, cu proveniență verificată. Fiecare crate în plus e o verigă în plus. Preferă un arbore mic și fii atent la nume „aproape corecte” și la salturi neobișnuite de versiune.
Ce reținem
Incidentul a fost prins repede, în circa două ore, fiindcă cercetătorii urmăresc registrele. Dar fereastra a existat, iar arrayref e într-un lanț care ajunge la sute de mii de proiecte.
Lecția nu e „Rust e nesigur”. E că securitatea unui limbaj și securitatea lanțului lui de aprovizionare sunt două lucruri diferite, apărate diferit. Memory safety o primești din compilator. Supply-chain safety o construiești: cargo deny, vendoring, build offline, pinning, CI izolat.
Vrei să știi ce dependențe intră de fapt în build-urile tale și cine le poate schimba? Scrie-ne și pornim de la un audit al lanțului de aprovizionare software.
Surse
Întrebări frecvente
Ce s-a întâmplat cu crate-ul arrayref?
Pe 20 august 2026, trei crate-uri Rust populare (arrayref, append-only-vec, internment) au fost otrăvite prin preluarea contului mentainerului. Codul upstream a rămas neatins, dar atacatorul a injectat o dependență pe proc-macro1, un typosquat al popularului proc-macro2, care rula un infostealer la compilare prin build.rs. arrayref are 245 de milioane de descărcări.
De ce nu te apără Rust în acest caz?
Fiindcă memory safety elimină bug-uri în codul pe care îl scrii tu (buffer overflow, use-after-free), nu atacurile de supply chain. Un build.rs malițios rulează cu drepturile compilării, indiferent cât de memory-safe e restul programului. Garanția limbajului se oprește la codul pe care îl controlezi, iar dependența ostilă e deja înăuntru.
De ce e periculos build.rs?
Pentru că se execută automat la compilare, deci un simplu cargo build rulează cod terț pe stația dezvoltatorului sau pe runner-ul de CI, cu drepturile utilizatorului. E un nivel pe care antivirusul și EDR-ul rareori îl monitorizează. Același tipar ca postinstall la npm.
Cum mă apăr?
Cu igiena de supply chain: cargo deny pe surse și advisories (prinde o dependență nouă, necunoscută), vendoring și build offline (nu tragi versiuni nou-publicate), pinning cu Cargo.lock (versiunea otrăvită nu ajunge în build), CI izolat (build.rs rulează cod terț) și mai puține dependențe, cu atenție la nume aproape corecte.