123% meer gemelde CVE's per dag in 2026 dan vorig jaar.

Softwareketen

Wat is dependency confusion?

Dependency confusion is een aanval waarbij een build het openbare pakket van een aanvaller installeert in plaats van uw privépakket met dezelfde naam. Niemand maakt een typefout. De aanvaller hoeft alleen een interne pakketnaam te achterhalen en die met een hoog versienummer op een openbare registry te publiceren, en een verkeerd geconfigureerde build doet de rest.

Bijgewerkt op

Hoe een aanval met dependency confusion werkt

  1. Een interne naam vinden. Namen van privépakketten lekken uit via openbare code, JavaScript-bundels, foutmeldingen en manifests die in repositories zijn achtergebleven.
  2. Dezelfde naam openbaar publiceren. De aanvaller registreert hem op npm, PyPI of een andere openbare registry, met een zeer hoog versienummer.
  3. Wachten op een build. Een pakketbeheerder die zowel de interne als de openbare registry raadpleegt, vindt twee kandidaten en geeft de voorkeur aan de hogere versie.
  4. Draaien binnen het bedrijf. Het installatiescript van het pakket draait op de machine van een ontwikkelaar of op een CI-runner, met toegang tot alles wat daar aanwezig is.

Het onderzoek dat het een naam gaf

In februari 2021 publiceerde beveiligingsonderzoeker Alex Birsan de techniek. Hij had die gebruikt om code te laten draaien binnen meer dan 35 organisaties, waaronder Apple, Microsoft en PayPal, in het kader van bugbountyprogramma's of met toestemming. Het werkte in alle drie de talen die hij testte, en aanvallers begonnen het binnen enkele dagen na de publicatie na te doen.

Waarom het gebeurt

De hoofdoorzaak is een pakketbeheerder die meerdere registries als gelijkwaardig behandelt. Het klassieke voorbeeld is Python: --extra-index-url van pip voegt naast PyPI een tweede bron toe, en pip kan het openbare pakket installeren als het er een met dezelfde naam vindt.

# 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 heeft hetzelfde probleem met interne namen zonder scope, terwijl een scope die aan uw registry is gekoppeld het voorkomt.

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

Hoe u dependency confusion voorkomt

  • Gebruik één bron van waarheid. Laat builds verwijzen naar één interne registry die openbare pakketten proxyt, en configureer die zo dat interne namen nooit openbaar worden opgelost.
  • Gebruik scopes of namespaces. Zorg dat een scope zoals @acme op de openbare registry van u is, en koppel die aan uw privéregistry.
  • Reserveer uw namen. Registreer interne pakketnamen op openbare registries, zodat niemand anders dat kan doen.
  • Vergrendel en verifieer. Commit een lockfile en gebruik hashcontrole, zoals --require-hashes van pip, zodat een ander pakket de installatie laat mislukken. Zie wat een lockfile wel en niet doet.
  • Beperk waarmee builds verbinding kunnen maken. Als een build alleen uw registry kan bereiken, kan hij het pakket van de aanvaller helemaal niet ophalen. Zie egressbeleid voor GitHub Actions.
  • Controleer wat u lekt. Doorzoek openbare code en clientbundels op uw interne pakketnamen.

Dependency confusion vs typosquatting

Typosquatting rekent erop dat iemand zich vertypt in de naam van een openbaar pakket. Dependency confusion gebruikt de exacte naam van een privépakket en rekent op de manier waarop de build is geconfigureerd. Beide komen op hetzelfde neer: code van de aanvaller die in uw build draait. Zie wat is een aanval op de softwareketen voor hoe ze zich verhouden tot andere aanvallen.

Hoe u ontdekt of u bent getroffen

Zoek naar interne pakketnamen die vanuit een openbare registry zijn opgelost, of naar versies die niet bestaan in uw interne registry. Dat is lastig op basis van alleen een lockfile, want de vraag is waar een pakket tijdens de build daadwerkelijk vandaan kwam.

Hoe CRACI helpt

CRACI werkt op het punt waar het pakket wordt opgehaald. Als uw GitHub Actions-runner handhaaft het een egressbeleid met getypeerde bronnen voor registries, zodat een build kan worden beperkt tot de registries die u toestaat. Het legt ook elk pakket dat elke job heeft opgehaald, vast in een SBOM, zodat u kunt zien wat een build is binnengekomen. CRACI detecteert niet dat een pakket kwaadaardig is, dus houd uw registryconfiguratie aan als eerste verdedigingslinie. Zie best practices voor ketenbeveiliging van software.

Dependency confusion: veelgestelde vragen

Wat is een aanval met dependency confusion?

Een aanval waarbij per ongeluk een openbaar pakket wordt geïnstalleerd met dezelfde naam als een privépakket, omdat de pakketbeheerder beide registries raadpleegt en de hogere versie verkiest.

Hoe verschilt dependency confusion van typosquatting?

Typosquatting rekent erop dat iemand zich vertypt in de naam van een openbaar pakket. Dependency confusion gebruikt de exacte naam van een privépakket en rekent op een buildconfiguratie die openbare registries raadpleegt.

Hoe voorkomt u dependency confusion?

Gebruik één interne registry, pakketnamen met een scope, lockfiles met hashcontroles en regels die beperken welke registries uw builds kunnen bereiken. Ook helpt het om uw interne namen openbaar te reserveren.

Is --extra-index-url veilig?

Niet voor privépakketten. Beide indexen worden daarmee kandidaten, dus een openbaar pakket met dezelfde naam kan worden geïnstalleerd. Gebruik --index-url met één index die u beheert.

Wie heeft dependency confusion ontdekt?

Beveiligingsonderzoeker Alex Birsan publiceerde de techniek in februari 2021, nadat hij die had gebruikt tegen meer dan 35 organisaties, in het kader van bugbountyprogramma's of met toestemming.

Beperk de bronnen van uw builds

Sta alleen de registries toe die een GitHub Actions-job nodig heeft, en zie elk pakket dat hij binnenhaalde.

Demo boeken