Her er ingen udnyttelse og ingen sårbarhed at lappe. Nogen registrerer et pakkenavn ét tastetryk fra et bibliotek, du bruger, og venter på, at en udvikler taster det. Forsvaret er opdagelse, for der er ikke noget at rette.

Det er en af fem veje ind i en software-forsyningskæde, og den billigste. Typosquatting er gammelt på nettet — domæner ét bogstav fra en banks — og det flyttede næsten uændret over i pakke-registries, med én vigtig forskel. Besøger du et lookalike-domæne, ser du en side, du måske opdager er forkert. Installerer du en lookalike-pakke, kører der kode på din maskine, før du kigger på noget som helst.

De fire former, det tager

Angribere vælger ikke navne tilfældigt. Varianterne samler sig i en håndfuld mønstre, alle valgt fordi de overlever et hurtigt blik:

  • Ombytning — to nabobogstaver byttet om, som reqeusts for requests. Næsten usynligt ved hurtig læsning, fordi vi læser ordbilleder og ikke bogstaver.
  • Udeladelse eller fordobling — et tegn, der mangler eller er gentaget, som loadash eller expresss.
  • Skilletegnsforvirring — bindestreg over for underscore over for ingenting. Økosystemer har forskellige konventioner, så en udvikler, der skifter mellem dem, gætter jævnligt forkert.
  • Visuelt forvekslelige tegn — ASCII-tegn, der læses som hinanden ved et hurtigt blik: rn for m, 1 for l, 0 for O. Ægte Unicode-homoglyffer, som et kyrillisk а, er domænenavne-udgaven af angrebet og er blokeret af både npm og PyPI, som begrænser pakkenavne til ASCII.

Hvorfor payloaden som regel kører med det samme

Den vigtige detalje er, at en typosquattet pakke sjældent har brug for, at du bruger den. Flere store pakkeværktøjer lader en pakke køre scripts ved installation — npm og dets slægtninge kører preinstall og postinstall, og en Python-kildedistribution udfører setup.py — og det er dér, payloaden ligger. Wheels, Maven og Cargo gør ikke, og derfor står npm- og PyPI-økosystemerne for de fleste registrerede hændelser.

Så forløbet er: en udvikler taster et navn forkert, installationen lykkes, et post-install-script kører med den udviklers rettigheder, og det læser miljøvariabler, cloud-nøglefiler og SSH-nøgler og sender dem videre. Derefter opdager udvikleren, at importen ikke virker, afinstallerer pakken og retter tastefejlen. Oplysningerne er allerede væk.

Det er også derfor, afhængigheder, der kun bruges under udvikling, fortjener omtanke. Et sårbart build-værktøj kan ikke nås af en angriber i produktion, men et ondsindet build-værktøj kører på maskinen hos hver udvikler, der installerer det, og på hver CI-server i pipelinen — hvilket på flere måder er et bedre mål end produktion.

Sådan virker detektionen, og hvor den går galt

Standardteknikken er redigeringsafstand: beregn hvor mange enkelttegns-ændringer der skiller et pakkenavn fra et kendt populært. En afstand på et eller to fra en meget populær pakke er mistænkelig; identisk er fint; langt væk er fint.

Vanskeligheden handler udelukkende om falske positive, og de har to kilder.

Legitime familier af pakker. Rigtige økosystemer er fulde af navne, der bevidst adskiller sig med ét tegn: et plugin opkaldt efter sit værtsbibliotek, officielle og fællesskabsvarianter, forks med scope. Et naivt afstandstjek markerer dem alle og lærer med det samme folk at afvise fundet.

Korte navne. Under omkring fem tegn ligger næsten alt inden for én redigering fra noget andet, og målet holder op med at bære information. Korte navne kræver en højere tærskel.

Et tjek, der konstant udløser, er værre end intet tjek, for den ene sande positive lander i en strøm af støj, teamet allerede har lært at lukke.

Hvad man gør ved det

Commit en lockfile. Det er den enkelte vane, der giver mest. Med en lockfile er præcise navne og versioner fastlåst, og enhver ændring dukker op i en diff — så en tastefejl bliver en synlig linje i en pull request og ikke noget, der skete i stilhed på én maskine.

Foretræk kopiér-indsæt i stedet for at taste, når du tilføjer en afhængighed, og tag den fra den officielle dokumentation og ikke fra et søgeresultat eller et forumsvar.

Behandl et uventet installationsscript som noget, der er værd at læse. De fleste pakker har ikke brug for et.

Installér uden scripts, hvor du kan. npm ci --ignore-scripts i CI fjerner hele udførelsesvejen ved installation for de pakker, der ikke reelt har brug for den, og tvinger dem, der har, frem i lyset.

Har du installeret en lookalike, så udskift nøglerne. At afinstallere fjerner pakken, ikke konsekvenserne. Gå ud fra, at alt, den proces kunne læse, er blevet læst.

Hvad er typosquatting i pakke-registries?

Typosquatting er, når en angriber udgiver en pakke, hvis navn ligger et eller to tegn fra et populært bibliotek — en ombytning som reqeusts for requests, et fordoblet bogstav, en bindestreg hvor der skulle stå underscore, eller et lookalike-tegn fra et andet alfabet — og venter på, at en udvikler taster navnet forkert. Der er ingen sårbarhed involveret og intet at lappe; angrebet er selve navnet.

Hvad sker der, hvis jeg installerer en typosquattet pakke?

En typosquattet pakke kører som regel sin last med det samme, uden at du overhovedet importerer den, fordi flere store pakkeværktøjer lader en pakke køre scripts ved installation. En typisk payload læser miljøvariabler, cloud-nøglefiler og SSH-nøgler og sender dem til angriberen. At opdage fejlen og afinstallere gør det ikke ugjort — alt, den proces kunne læse, bør betragtes som kompromitteret og udskiftes.

Hvordan opdager man typosquatting?

Typosquatting opdages med redigeringsafstand: man måler, hvor mange enkelttegns-ændringer der skiller et pakkenavn fra et kendt populært, og markerer navne, der ligger en eller to redigeringer væk. Vanskeligheden er falske positive, fordi rigtige økosystemer er fulde af legitime navne, der bevidst adskiller sig med ét tegn — plugins opkaldt efter deres værtsbibliotek, officielle og fællesskabsvarianter — og fordi navne under omkring fem tegn ligger inden for én redigering fra næsten alt. Et tjek, der konstant udløser, bliver ignoreret, og det er værre end intet tjek.

Hvordan beskytter jeg mit projekt mod typosquatting?

Commit en lockfile, hvilket er den mest værdifulde vane: præcise navne og versioner er fastlåst, så enhver ændring dukker op i en pull request-diff i stedet for at ske i stilhed på én maskine. Kopiér afhængighedsnavne fra den officielle dokumentation i stedet for at taste dem eller tage dem fra forumsvar, og behandl et uventet installationsscript som noget, der er værd at læse, eftersom de fleste pakker ikke har brug for et.

Hvor CodeControl passer ind

CodeControl sammenligner dine pakkenavne mod lister over populære pakker offline, med en højere tærskel for korte navne, så tjekket forbliver stille nok til at være værd at læse. Det kører side om side med malware-feedet, der fanger bekræftet ondsindede pakker uanset navn, og med tjek af pakkers omdømme, der fanger de nyregistrerede navne, en AI-assistent opfandt — et angreb, typosquat-detektion er strukturelt blind over for.