Vuonna 2026 raportoitiin päivässä 131% enemmän CVE:itä kuin edellisenä vuonna.

Toimitusketju

Mitä on dependency confusion?

Dependency confusion on hyökkäys, jossa buildi asentaa hyökkääjän julkisen paketin samannimisen yksityisen pakettisi sijaan. Kukaan ei tee kirjoitusvirhettä. Hyökkääjän tarvitsee vain selvittää sisäisen paketin nimi ja julkaista se julkisessa rekisterissä suurella versionumerolla, ja väärin konfiguroitu buildi hoitaa loput.

Päivitetty

Miten dependency confusion -hyökkäys toimii

  1. Sisäisen nimen löytäminen. Yksityisten pakettien nimet vuotavat julkisen koodin, JavaScript-bundlejen, virheilmoitusten ja repositorioihin jääneiden manifestien kautta.
  2. Saman nimen julkaiseminen julkisesti. Hyökkääjä rekisteröi nimen npm:ään, PyPI:hin tai muuhun julkiseen rekisteriin hyvin suurella versionumerolla.
  3. Buildin odottaminen. Paketinhallinta, joka on asetettu tarkistamaan sekä sisäinen että julkinen rekisteri, löytää kaksi ehdokasta ja suosii suurempaa versiota.
  4. Suoritus yrityksen sisällä. Paketin asennusskripti ajetaan kehittäjän koneella tai CI-runnerilla, ja sillä on pääsy kaikkeen, mitä siellä on.

Tutkimus, joka antoi hyökkäykselle nimen

Tietoturvatutkija Alex Birsan julkaisi tekniikan helmikuussa 2021. Hän oli saanut sen avulla koodia ajoon yli 35 organisaatiossa, muun muassa Applella, Microsoftilla ja PayPalilla, bug bounty -ohjelmien puitteissa tai luvan kanssa. Tekniikka toimi kaikilla kolmella hänen testaamallaan kielellä, ja hyökkääjät alkoivat kopioida sitä muutamassa päivässä julkaisusta.

Miksi näin käy

Perimmäinen syy on paketinhallinta, joka kohtelee useita rekistereitä tasavertaisina. Klassinen esimerkki on Python: pipin --extra-index-url lisää PyPI:n rinnalle toisen lähteen, ja pip voi asentaa julkisen paketin, jos se löytää samannimisen.

# Unsafe for private packages: both indexes are candidates
pip install --extra-index-url https://pypi.internal.example/simple my-internal-lib

# Safer: one index you control, which proxies public packages
pip install --index-url https://pypi.internal.example/simple my-internal-lib

npm:llä on sama ongelma scopettomien sisäisten nimien kanssa, kun taas rekisteriisi sidottu scope välttää sen.

# .npmrc: everything under @acme comes only from your registry
@acme:registry=https://npm.internal.example/

Miten dependency confusion estetään

  • Käytä yhtä totuuden lähdettä. Ohjaa buildit yhteen sisäiseen rekisteriin, joka välittää julkiset paketit, ja määritä se niin, ettei sisäisiä nimiä koskaan haeta julkisesta lähteestä.
  • Käytä scopeja tai nimiavaruuksia. Ota julkisesta rekisteristä omistukseesi scope, kuten @acme, ja ohjaa se yksityiseen rekisteriisi.
  • Varaa nimesi. Rekisteröi sisäisten pakettien nimet julkisiin rekistereihin, jotta kukaan muu ei voi tehdä niin.
  • Lukitse ja varmenna. Tallenna lukitustiedosto (lockfile) versionhallintaan ja käytä tiivistetarkistusta, kuten pipin --require-hashes, jotta eri paketti kaataa asennuksen. Katso mitä lukitustiedosto tekee ja mitä ei.
  • Rajoita, mihin buildit voivat yhdistää. Jos buildi pääsee vain rekisteriisi, se ei voi hakea hyökkääjän pakettia lainkaan. Katso GitHub Actionsin egress-käytäntö.
  • Tarkista, mitä vuodat. Etsi sisäisten pakettiesi nimiä julkisesta koodista ja asiakaspuolen bundleista.

Dependency confusion vs. typosquatting

Typosquatting perustuu siihen, että joku kirjoittaa julkisen paketin nimen väärin. Dependency confusion käyttää yksityisen paketin tarkkaa nimeä ja perustuu siihen, miten buildi on konfiguroitu. Molemmat päätyvät samaan: hyökkääjän koodi ajetaan buildissasi. Katso mikä on toimitusketjuhyökkäys, niin näet, miten ne liittyvät muihin hyökkäyksiin.

Miten tiedät, osuiko hyökkäys sinuun

Etsi sisäisiä paketinnimiä, jotka on haettu julkisesta rekisteristä, tai versioita, joita sisäisessä rekisterissäsi ei ole. Pelkästä lukitustiedostosta sitä on vaikea selvittää, koska kysymys on siitä, mistä paketti buildin aikana todella tuli.

Miten CRACI auttaa

CRACI toimii siinä kohdassa, jossa paketti haetaan. GitHub Actions -runnerinasi se valvoo egress-käytäntöä, jossa rekistereille on tyypitetyt lähteet, joten buildin voi rajata sallimiisi rekistereihin. Lisäksi se tallentaa SBOM:iin jokaisen paketin, jonka kukin jobi haki, joten näet, mitä buildiin tuli. CRACI ei tunnista, onko paketti haitallinen, joten pidä rekisterikonfiguraatiosi ensimmäisenä puolustuslinjana. Katso ohjelmistotoimitusketjun tietoturvan parhaat käytännöt.

Dependency confusion: usein kysytyt kysymykset

Mikä on dependency confusion -hyökkäys?

Hyökkäys, jossa yksityisen paketin kanssa samanniminen julkinen paketti asennetaan vahingossa, koska paketinhallinta tarkistaa molemmat rekisterit ja suosii suurempaa versiota.

Miten dependency confusion eroaa typosquattingista?

Typosquatting perustuu siihen, että joku kirjoittaa julkisen paketin nimen väärin. Dependency confusion käyttää yksityisen paketin tarkkaa nimeä ja perustuu build-konfiguraatioon, joka tarkistaa julkiset rekisterit.

Miten dependency confusion estetään?

Käytä yhtä sisäistä rekisteriä, scopeilla nimettyjä paketteja, lukitustiedostoja tiivistetarkistuksin sekä sääntöjä, jotka rajaavat, mihin rekistereihin buildisi pääsevät. Myös sisäisten nimien varaaminen julkisesti auttaa.

Onko --extra-index-url turvallinen?

Ei yksityisille paketeille. Se tekee molemmista indekseistä ehdokkaita, joten samanniminen julkinen paketti voidaan asentaa. Käytä --index-url-asetusta yhdellä hallitsemallasi indeksillä.

Kuka löysi dependency confusionin?

Tietoturvatutkija Alex Birsan julkaisi tekniikan helmikuussa 2021 käytettyään sitä yli 35 organisaatiota vastaan bug bounty -ohjelmien puitteissa tai luvan kanssa.

Rajaa, mistä buildisi voivat hakea

Salli vain ne rekisterit, joita GitHub Actions -jobi tarvitsee, ja näe jokainen paketti, jonka se haki.

Varaa demo