Anatomia unui lanț de dependențe compromise: ce găsești într-un audit de supply-chain
de Claudiu Hulea · IT Management Consultant
Într-un audit al lanțului de aprovizionare software (supply-chain) am identificat un lanț de dependențe compromise: pachete populare care, printr-un truc de tip typosquat, trăgeau biblioteci malițioase cu nume aproape identice cu ale celor legitime. Cel mai interesant nu a fost atacul în sine, ci capcana din remediere: „reparația“ automată recomandată de instrumente ducea înapoi, direct în versiunile infectate. Iată anatomia și ce ai de făcut.
Ce este un atac pe lanțul de aprovizionare software?
E atacul în care nu ești ținta directă, ci codul de care depinzi. Aplicațiile moderne asamblează sute de pachete open-source, iar fiecare aduce, la rândul lui, alte pachete (dependențe tranzitive). E suficient ca un singur pachet din acest arbore să fie compromis pentru ca payload-ul să ajungă pe mașinile tale de dezvoltare și în pipeline-ul de build — fără să atingă nimeni „aplicația“ ta.
Ce am descoperit în audit?
Un pachet extrem de răspândit din ecosistemul npm fusese modificat astfel încât să depindă de două biblioteci typosquat — nume aproape identice cu ale unor utilitare foarte cunoscute:
obugîn loc dedebugpiccoloreîn loc depicocolors
Substituția era discretă: la instalare, arborele de dependențe le aducea automat, iar codul lor se executa la fiecare build. Cazul e documentat public într-un advisory de securitate (vezi Surse). Nu e o teorie — e tiparul clasic al unui dependency-chain dropper.
De ce e periculos un typosquat de dependență?
- Rulează la build time, pe stațiile de dezvoltare și pe runner-ele de CI — un nivel pe care antivirusul și EDR-ul de pe endpoint-uri rareori îl monitorizează.
- Intervalele „caret“ (
^) din manifeste înseamnă că o versiune nouă, malițioasă, poate fi trasă automat la următoarea instalare, fără nicio acțiune din partea ta. - E tranzitiv: nu tu ai cerut pachetul rău, ci o dependență a unei dependențe — deci nu apare în lista ta „directă“ și e ușor de ratat.
Capcana: când „reparația“ automată te duce înapoi în problemă
Aici a fost partea instructivă. Rulând auditul automat de securitate al managerului de pachete, „remedierea“ sugerată (fix --force) ducea către versiuni mai noi care tot conțineau typosquații — un fix care de fapt reintroducea problema.
Mai mult, atacatorul nu modificase doar lista de dependențe, ci și codul sursă al pachetului, ca să folosească API-ul bibliotecii malițioase. Consecința: nu poți „păcăli“ build-ul cu o simplă redirecționare (override) către biblioteca reală — se rupe. Singura cale curată e fixarea pe ultimele versiuni upstream genuin curate, verificate manual.
Acesta e lanțul complet de vulnerabilitate: dependență substituită → cod executat la build sub radar → remediere automată care întărește problema → sursă modificată care blochează scurtăturile.
Cum te aperi?
- Tratează lockfile-ul ca pe cod. Fixează versiuni exacte și revizuiește orice modificare a arborelui de dependențe în PR, nu doar codul tău.
- Nu rula orbește
audit fix --force. Verifică manual ce versiune propune și dacă e într-adevăr curată (npm view <pachet> dependencies) înainte să o accepți. - Inventar de componente (SBOM). Trebuie să știi ce pachete, inclusiv tranzitive, intră în build.
- Verifică proveniența (semnături/OIDC) și fii atent la salturi neobișnuite de versiune sau la dependențe cu nume „aproape corecte“.
- Izolează CI-ul. Runner-ele care fac build execută cod terț; limitează-le accesul și rotește periodic credențialele accesibile din mediul de build.
- Preferă mai puține dependențe și elimină componentele nementinute — fiecare pachet în plus e o verigă în plus care poate ceda.
Ce reținem
Lanțul de aprovizionare software este suprafața de atac reală a aplicațiilor moderne, iar scanările automate, oricât de utile, nu văd tot — uneori chiar te trimit înapoi în problemă. Un audit de securitate dedicat analizează arborele de dependențe, lockfile-ul și pipeline-ul cu ochi critic, iar un test de penetrare confirmă ce e cu adevărat exploatabil. Diferența dintre „am rulat un scan“ și „am înțeles lanțul“ e exact diferența dintre a repara și a crede că ai reparat.
Surse
Întrebări frecvente
Ce este un atac typosquat pe lanțul de dependențe?
Un atac în care un pachet popular e modificat să tragă biblioteci malițioase cu nume aproape identice cu ale celor legitime (ex. `obug` în loc de `debug`, `piccolore` în loc de `picocolors`). La instalare, arborele de dependențe le aduce automat, iar codul lor se execută la fiecare build — pe stațiile de dezvoltare și pe runner-ele de CI.
De ce e periculos un typosquat de dependență?
Rulează la build time, un nivel pe care antivirusul și EDR-ul rareori îl monitorizează; e tranzitiv (nu tu ai cerut pachetul rău, ci o dependență a unei dependențe), deci scapă listei „directe"; iar intervalele caret (`^`) pot trage automat o versiune nouă malițioasă la următoarea instalare.
De ce „reparația" automată nu rezolvă problema?
Pentru că, în cazul documentat, `audit fix --force` propunea versiuni mai noi care tot conțineau typosquații — reintroducea problema. În plus, atacatorul modificase și codul sursă al pachetului, deci un simplu override către biblioteca reală rupe build-ul. Singura cale curată e fixarea pe ultimele versiuni upstream genuin curate, verificate manual.
Cum mă apăr?
Tratează lockfile-ul ca pe cod (fixează versiuni exacte, revizuiește modificările arborelui în PR), nu rula orbește `audit fix --force`, ține un SBOM, verifică proveniența (semnături/OIDC), izolează CI-ul și rotește credențialele accesibile din build, și preferă mai puține dependențe.