Articles
Sep 9, 2025

Globalni sigurnosni propust na npm-u

Milijarde preuzimanja izložene riziku.

Globalni sigurnosni propust na npm-u

Uvod u incident

Početkom rujna 2025. zabilježen je jedan od najvećih supply chain napada u povijesti npm ekosustava. Dana 8. rujna 2025., napadači su kompromitirali korisnički račun istaknutog održavatelja na npm-u te ubacili maliciozni kod u više iznimno popularnih paketa. Napad je rezultirao time da su legitimne verzije paketa zamijenjene malicioznim inačicama, koje su sadržavale malware usmjeren na krađu kriptovaluta kroz preglednike korisnika. Zbog ogromne raširenosti tih paketa (preko 2 milijarde preuzimanja tjedno), incident je uzdrmao zajednicu i istaknuo rastuće rizike u lancu softverske opskrbe.


Način napada: phishing održavatelja

Do kompromitacije je došlo pomoću ciljane phishing prijevare usmjerene na održavatelja paketa. Napadači su poslali uvjerljiv e-mail koji se lažno predstavljao kao poruka od npm podrške (s domene npmjs.help umjesto službenog npmjs.com). U poruci se od održavatelja (Josh Junon, poznat pod nadimkom Qix) zahtijevalo da ažurira svoje 2FA vjerodajnice pod prijetnjom blokade računa nakon 10. rujna 2025. Poruka je stvarala lažni osjećaj hitnosti i izgledala legitimno, zbog čega je inače oprezan održavatelj nažalost nasjeo na prevaru.

Klikom na priloženi link otvorila se lažna stranica za prijavu na kojoj je zatraženo korisničko ime, lozinka te jednokratni 2FA kod. Neposredno nakon što je održavatelj upisao tražene podatke, oni su presretnuti i proslijeđeni napadaču (vjerojatno putem adversary-in-the-middle tehnike), čime je napadač dobio potpuni pristup npm računu održavatelja. U vrlo kratkom roku, taj je pristup iskorišten za objavu novih, zloćudnih verzija popularnih paketa pod održavateljevim imenom.


Kompromitirani npm paketi

Incident je zahvatio oko dvadeset popularnih npm paketa s više od dvije milijarde tjednih preuzimanja, prema ranim izvješćima sigurnosnih medija. To su bili neki od najrasprostranjenijih modula u JavaScript ekosustavu, što je ovom incidentu dalo iznimno širok doseg. Među pogođenim paketima nalaze se, između ostalih:

• chalk – popularna biblioteka za obojani ispis teksta u konzoli
• debug – široko korišten modul za ispis debuggiranja
• ansi-regex – pomoćna biblioteka za prepoznavanje ANSI kodova u stringovima
• ansi-styles – skup definicija stilova boja za terminal output
• supports-color – modul za detekciju podrške boja u terminalu
• strip-ansi – alat za uklanjanje ANSI escape kodova iz stringova
• wrap-ansi – biblioteka za prelamanje stringova s ANSI kodovima
• color-convert i color-name – pomoćne biblioteke za rad s bojama
• color-string – biblioteka za parsiranje i formatiranje boja
• error-ex – modul za proširenje objekata grešaka
• has-ansi – provjerava sadrži li string ANSI kod
• is-arrayish – pomoćna funkcija za provjeru ponaša li se objekt poput niza
• supports-hyperlinks – detektira podržavaju li terminali hiperveze
• simple-swizzle – utilita za manipulaciju argumentima (swizzling)
• chalk-template – dodatak za formatiranje tekstualnih predložaka uz chalk
• backslash – manji paket (koristi ga chalk) za upravljanje posebnim znakovima u stringovima

Svi navedeni paketi bili su upravljački ili pomoćni moduli koji čine temelje mnogih drugih biblioteka, pa je kompromitacija jednog održavatelja automatski dovela do kompromitacije brojnih projekata koji se indirektno oslanjaju na njih. Procjenjuje se da ti paketi zajedno bilježe oko 2,6 milijardi preuzimanja tjedno, što ilustrira razmjere potencijalne štete.

Ubačeni malware: što radi?

Zlonamjerni kod ubačen u navedene pakete bio je pažljivo skriven (obfuskiran) i dizajniran tako da se aktivira isključivo u kontekstu web-preglednika, ciljajući krajnje korisnike s kripto-novčanicima. Pri učitavanju kompromitiranog paketa u pregledniku, malware najprije provjerava postoji li window objekt - na taj način utvrđuje radi li u browser okruženju. U takvom okruženju, odmah preuzima kontrolu nad ključnim funkcijama za mrežnu komunikaciju i blockchain interakciju:

• Presreće pozive prema Web3/kriptografskim sučeljima: primjerice, hooka objekt window.ethereum (koji koriste Ethereum novčanici poput MetaMaska) te njegove metode za slanje transakcija. Time može neprimjetno preusmjeriti odlazne transakcije - npr. kad aplikacija zatraži slanje sredstava na neku adresu, malware ubacuje svoju adresu umjesto odredišne, prije nego što korisnik potpiše transakciju.

• Manipulira fetch API-jem i XMLHttpRequest-om: redefinira globalne metode za web zahtjeve (window.fetch, kao i XMLHttpRequest.open/send) kako bi pratio sav promet prema poslužiteljima. Kada u povratnim podacima (obično JSON odgovorima API-ja) detektira niz koji izgleda kao adresa kriptovalute, on ga zamjenjuje drugom adresom napadača. Zamjenske adrese pažljivo su odabrane da budu vizualno slične originalnima, koristi se algoritam usporedbe stringova (Levenshteinova udaljenost) kako bi nova adresa imala minimalna odstupanja od izvorne. Time se nastoji zavarati korisnika da ne primijeti promjenu adrese pri površnom provjeravanju.

• Podržava više blockchaina: Iako je primarno usmjeren na Ethereum, zloćudni kod prepoznaje i druge lance (Bitcoin, Litecoin, Solana, Tron, itd.) te sadrži popise adresa napadača za razne formate (npr. adrese koje počinju s "1" ili "bc1" za BTC, ili "T" za Tron). U slučaju Solane, primjerice, malware bi zamjenom ključnih parametara onemogućio valjanost transakcije ili je preusmjerio na fiksnu adresu pod napadačevom kontrolom.

• Stealth mehanizmi: Kod je bio snažno obfuskiran (prepun besmislenih varijabla poput _0x... i zakodiranih tablica znakova) kako bi se izbjeglo otkrivanje pregledom izvornog koda. Također, malware definira globalni objekt stealthProxyControl preko kojeg je napadač mogao upravljati nekim aspektima malicioznog koda, što otežava otkrivanje prosječnim korisnicima. Prilikom izvođenja, nastojao je ne izazvati sumnjive vidljive efekte u sučelju aplikacije; primjerice, nakon što bi preusmjerio transakciju, često bi vratio lažan "uspješan" odgovor aplikaciji kako bi sve izgledalo uredno.

Ovakav browser-based pristup znači da primarni cilj napada nisu bili sami razvojni inženjeri, već krajnji korisnici aplikacija koje učitavaju kompromitirane pakete. Ako bi korisnik posjetio web-stranicu ili aplikaciju koja uključuje zaraženi paket te pri tome imao povezan kripto-novčanik, malware bi mogao presresti i izmijeniti njegove transakcije u stvarnom vremenu, potencijalno preusmjeravajući sredstva napadačima, a da ni razvojni tim aplikacije ni korisnik toga nisu odmah svjesni.


Opseg napada i posljedice

Opseg ovog napada bio je ogroman. Zahvaćeni paketi zajedno su dosezali više od 2 milijarde preuzimanja tjedno, što implicira da je praktički svaki kutak JavaScript ekosustava mogao biti dotaknut. Mnogi projekti povlačili su ove pakete neizravno (kao transitivne ovisnosti), pa su potencijalno tisuće aplikacija i web-stranica u kratkom roku ugradile kompromitirani kod, nesvjesne što se dogodilo. Srećom, zajednica je reagirala iznimno brzo: unutar otprilike dvije ure od prvog pojavljivanja zloćudnih verzija, otkrivene su sumnjive izmjene i podignuta je uzbuna na GitHubu, nakon čega su održavatelji vratili prethodne (čiste) verzije i uklonili kompromitirane iz npm repozitorija. Npm je ubrzo potom zaključao pogođene račune i označio pakete kao ugrožene, spriječivši daljnju distribuciju malwarea.

Paradoksalno, konkretna financijska šteta od napada ispala je vrlo mala. Iako su napadači uspjeli postići iznimno široku distribuciju svog malwarea, čini se da gotovo nisu ostvarili materijalnu korist. Prema dostupnim izvještajima, identificirano je da je na napadačke kripto-adrese preusmjereno svega oko 0.05 USD (5 centi) u Etheru te oko 20 USD jedne manje poznate kriptovalute, ukupno dakle manje od 50 USD vrijednosti.

Ovaj zanemariv iznos sugerira da su napadači ili požurili s napadom pa nisu stigli “unovčiti” prije nego što je otkriven, ili je vrlo malo krajnjih korisnika zapravo pokrenulo situacije u kojima bi malware reagirao (npr. slalo transakcije) tijekom onog kratkog intervala dok su zaraženi paketi bili aktivni. Najveća “cijena” ovog incidenta zapravo se ogleda u neposrednom trošku sanacije, tisuće sati inženjerskog rada utrošenog na provjere i čišćenje projekata, te u povećanoj svijesti (i zabrinutosti) za sigurnost supply chaina, što će posljedično pokrenuti dodatna ulaganja u sigurnosne alate i procese.

Zašto je ovaj napad posebno opasan?

Ovaj incident naglašava koliko su supply chain napadi opasni u modernom razvoju softvera. Umjesto da direktno napadnu dobro branjene sustave kompanija, napadači su udarili na povjerenje u otvoreni kod, iskoristili su činjenicu da razvojne zajednice masovno koriste open-source pakete i implicitno vjeruju njihovim održavateljima. Nekoliko je ključnih razloga zašto je upravo ovaj napad izazvao toliku zabrinutost:

• Duboke ovisnosti: Mnogi od kompromitiranih paketa (poput chalk, debug i ANSI utility biblioteka) nalaze se duboko u lancu ovisnosti bezbroj drugih modula. Razvojni timovi ih često ne uključuju direktno, ali oni dolaze transitivno - npr. kao ovisnost neke druge biblioteke na koju se oslanjate. To znači da velik broj projekata može biti pogođen, a da njihovi autori uopće nisu svjesni da koriste te pakete. Jedna uspješna kompromitacija tako se “kaskadno” prenosi na cijeli ekosustav.

• Popularnost i raširenost: Kompromitirani paketi spadaju među najpreuzimanije na npm-u (stotine milijuna preuzimanja tjedno po paketu). Napadači su strateški odabrali mete čije bi preuzimanje zloćudne verzije pružilo maksimalan domet. To je vjerojatno i razlog zašto ovakav tip napada privlači i napredne hakerske grupe – primjerice, zabilježeno je da sjevernokorejska grupa Lazarus cilja upravo popularne open-source projekte kako bi na taj način dosegla širok krug žrtava uz minimalan trud.

• Težina detekcije: Supply chain napadi oslanjaju se na činjenicu da se paketima vjeruje i da rijetko tko detaljno provjerava svaki update ovisnosti. U ovom slučaju, zlonamjerna verzija paketa izgledala je na prvi pogled kao i svaka druga (osim možda neuobičajeno velikog broja obfusciranih linija koda). Razvojni inženjeri prilikom ažuriranja paketa obično se oslanjaju na reputaciju autora i ne primijete ništa sumnjivo dok se ne dogodi nešto loše. Kada se malware vješto skriva i aktivira tek u specifičnim uvjetima (npr. u pregledniku uz kripto-transakcije), postoji velika šansa da prođe neko vrijeme prije nego li se uopće otkrije da nešto nije u redu.

• Brzina propagacije: U modernim CI/CD procesima, nove verzije biblioteka mogu se automatski povući i ugraditi u aplikacije unutar sati. U ovom slučaju, maliciozne verzije bile su dostupne samo dva sata, ali su i u tom kratkom razdoblju potencijalno tisuće projekata povukle upravo te verzije tijekom automatskih instalacija ili buildova. To ilustrira kako munjevito se posljedice mogu proširiti kad je ciljano srce ekosustava.

Sve navedeno čini supply chain napade izuzetno opasnima. Jedna kompromitirana karika u lancu može ugroziti čitav niz tvrtki i korisnika. S obzirom na to da su ovakvi napadi u porastu (u 2024. zabilježen je niz sličnih slučajeva na npm-u i PyPI-ju), ovaj incident služi kao ozbiljno upozorenje svima u softverskoj industriji.


Preporuke

Napad na npm pakete održavatelja Qix donio je vrijedne pouke o tome kako pojačati sigurnost otvorenog koda i spriječiti slične incidente u budućnosti. U nastavku su neke preporuke i dobre prakse koje su se nametnule nakon ovog događaja:

• Pažljivije sigurnosne provjere ovisnosti: Razvojni timovi trebaju uvesti naviku auditiranja svojih paketa - osobito prije i poslije ažuriranja. Preporuča se koristiti alate koji uspoređuju promjene u kodu novih verzija te mogu detektirati sumnjive dodatke (npr. iznenadna pojava obfusciranog koda ili nepotrebnih mrežnih poziva).

U kontekstu ovog napada, timovi su savjetovani da pregledaju svoje package-lock.json/yarn.lock datoteke kako bi utvrdili jesu li tijekom napada povukli kompromitirane verzije te da odmah vrate na zadnje poznato sigurno izdanje dotičnih paketa. Također, ima smisla zaključati („pinati“) verzije kritičnih paketa i ne žuriti s updateom dok se ne provjeri reputacija nove verzije.

• Primjena višefaktorske autentikacije (MFA) i opreza s pristupnim podacima: Svi održavatelji, ali i ostali developeri, trebali bi imati uključenu 2FA zaštitu na svojim računima (npm, GitHub, i dr.). No jednako je važno razumjeti da sama 2FA nije srebrni metak – u ovom slučaju održavatelj jest imao 2FA, ali ju je phishing napad zaobišao. Stoga se preporuča korištenje fizičkih sigurnosnih ključeva (U2F/WebAuthn) umjesto kodova generiranih aplikacijom, jer su hardverski ključevi puno otporniji na phishing (ne može se lako presresti jednokratni kod).

Nikada ne treba slijepo vjerovati e-mailovima koji traže ažuriranje lozinki ili 2FA podešavanja, uvijek provjerite adresu pošiljatelja (npr. npmjs.help vs. npmjs.com) i umjesto klikanja na priložene linkove, ručno otvorite službenu stranicu za provjeru statusa računa. Edukacija o prepoznavanju phishing poruka i razvoj zero-trust mentaliteta ključni su za izbjegavanje sličnih zamki.

• Kontinuirani nadzor i monitoring: Organizacije bi trebale implementirati sustave za nadzor integriteta koda u runtimeu. Primjerice, za web-aplikacije koje koriste osjetljive pakete, može se uvesti monitoring koji će alarmirati ako dođe do neuobičajenih ponašanja poput presretanja fetch poziva ili mijenjanja kripto-adresa u letu.

Neki sigurnosni alati koriste heuristike za detekciju obfusciranog JavaScript koda i sumnjivih globalnih objekata (poput stealthProxyControl u ovom malwareu), što može pomoći u ranijem otkrivanju prijetnje. Također, za aplikacije koje rukovode kripto-transakcijama, preporuka je ugraditi dodatne provjere, primjerice, prikazivati i tražiti potvrdu adrese na uređaju korisnika (hardverskom walletu) kako malware ne bi mogao zamijeniti adresu neprimijećeno.

• Suradnja i transparentnost u zajednici: Ovakvi incidenti pokazuju vrijednost brze razmjene informacija među sigurnosnim istraživačima, platformi i održavatelja. U ovom napadu, brza reakcija (Aikido Security je odmah obavijestio održavatelja, a on je putem Blueskyja i GitHub komentara alarmirao ostale) značajno je smanjila vrijeme izloženosti.

Zajednica bi trebala nastaviti razvijati alate i protokole za brzu distribuciju informacija o kompromitiranim paketima (primjerice, automatska upozorenja u paketnim managerima kada je neka verzija označena zlonamjernom). Također, platforme poput npm-a mogu razmotriti dodatne mjere zaštite za kritične održavatelje - npr. proširiti 2FA s obaveznim hardverskim ključevima za one koji održavaju pakete visokog utjecaja, ili uvesti mehanizme kode-sigurnosne provjere prije objave (code signing, manual review za vrlo popularne pakete, i sl.).

Na koncu, lesson learned cijelog događaja jest da je sigurnost lanca opskrbe softverom zajednička odgovornost. Brza detekcija i reakcija u ovom slučaju ograničile su štetu, ali to se ne smije prepustiti slučaju. Potrebna je stalno unapređenje sigurnosnih protokola i bliska suradnja između open-source zajednice, sigurnosnih stručnjaka i platformi kako bi se zaštitio ekosustav od sličnih prijetnji ubuduće. Slučaj npm napada iz rujna 2025. poslužio je kao bolan, ali vrijedan podsjetnik koliko je bitno neprekidno ulagati u sigurnost tijekom cijelog životnog ciklusa softvera.

// Newsletter //

Prijava na newsletter

Budite u toku s najnovijim sigurnosnim upozorenjima, analizama i praktičnim savjetima naših stručnjaka.

Thanks for joining our newsletter.
Oops! Something went wrong.
Subscribe To Our Weekly Newsletter - Cybersecurity X Webflow Template