Kennisbank

Module shadowing: hoe software per ongeluk het verkeerde onderdeel gebruikt

Bijgewerkt: 31 augustus 2026 · 7 min leestijd

Stel je voor dat je bedrijf een collega in dienst neemt die toevallig dezelfde naam heeft als een bestaande, vertrouwde medewerker: "Jan Bakker". Als iemand in een e-mail simpelweg "stuur het naar Jan Bakker" schrijft, kan het bericht bij de verkeerde persoon terechtkomen, met alle verwarring en risico's van dien. In softwareprogramma's kan iets vergelijkbaars gebeuren met stukjes code. Dat verschijnsel heet module shadowing, oftewel "module-overschaduwing": een zelfgeschreven of nieuw binnengehaald onderdeel van een programma krijgt toevallig dezelfde naam als een al bestaand, vertrouwd onderdeel, waardoor de computer het verkeerde onderdeel gebruikt.

Dat klinkt misschien als een onschuldige verwarring, maar het kan grote gevolgen hebben. Een programma kan onverwacht crashen of rare foutmeldingen geven, terwijl niemand meteen doorheeft waarom. Erger nog: kwaadwillenden hebben dit principe leren misbruiken om malware te verspreiden via software die bedrijven wereldwijd gebruiken. Module shadowing is daarmee niet alleen een technisch curiosum voor programmeurs, maar ook een onderwerp binnen digitale veiligheid, met steeds nieuwe varianten naarmate programmeren zelf verandert — bijvoorbeeld doordat kunstmatige intelligentie tegenwoordig meeschrijft aan code.

Wat is het precies?

Om module shadowing te begrijpen, moet je eerst weten wat een module is. Een module is een los, herbruikbaar stukje programmeercode — te vergelijken met een hoofdstuk in een instructieboek dat je apart kunt inladen wanneer je het nodig hebt. Programmeertalen zoals Python leveren standaard tientallen van zulke modules mee, bijvoorbeeld een module genaamd random die willekeurige getallen genereert.

Wanneer een programma om een module vraagt, moet de computer die ergens gaan zoeken. Dat proces heet importeren, en de computer doorzoekt daarvoor een vaste lijst van plekken, in een vaste volgorde. Bij Python is de eerste plek die wordt doorzocht meestal de map waarin het huidige programma zelf staat, en pas daarna de standaardbibliotheek en extra geïnstalleerde pakketten.

Dat volgordeprincipe is de kern van het probleem. Stel dat een beginnende programmeur een eigen bestand maakt en dat per ongeluk random.py noemt, zonder te beseffen dat dit dezelfde naam is als de ingebouwde module. Zodra het programma vervolgens "importeer random" uitvoert, vindt de computer eerst het eigen, lege bestand in de projectmap — en negeert de echte, ingebouwde module. Het programma crasht dan met een verwarrende foutmelding, terwijl de programmeur denkt dat er iets mis is met Python zelf.

Een nauw verwant begrip is variable shadowing, ofwel het overschaduwen van variabelen: een naam voor een stukje data (bijvoorbeeld "totaal") die binnen een klein onderdeel van het programma opnieuw wordt gebruikt, waardoor de oorspronkelijke waarde tijdelijk onbereikbaar wordt. Het onderliggende mechanisme — twee dingen met dezelfde naam, waarbij het ene het andere aan het zicht onttrekt — is vergelijkbaar, alleen dan op het niveau van een enkel gegeven in plaats van een hele module.

Niet elke programmeertaal lost dit op dezelfde manier op. JavaScript, de taal achter de meeste websites, gebruikt in de Node.js-omgeving een map genaamd node_modules waarin geïnstalleerde pakketten apart worden bewaard, los van de eigen broncode van een project. Dat maakt onbedoelde naamsbotsingen met ingebouwde onderdelen minder waarschijnlijk dan in Python, al blijft het risico bestaan zodra twee externe pakketten toevallig dezelfde naam claimen.

Wat wil men ermee bereiken?

Softwareontwikkelaars en onderzoekers besteden aandacht aan module shadowing om twee samenhangende redenen: voorspelbaarheid en veiligheid.

Ten eerste moet software zich voorspelbaar gedragen. Als een programmeur "random" importeert, wil die persoon zeker weten dat daadwerkelijk de bedoelde, vertrouwde module wordt gebruikt en niet per ongeluk een ander bestand met dezelfde naam. Onvoorspelbaar gedrag door shadowing veroorzaakt lastig te vinden bugs, omdat de foutmelding zelden direct verwijst naar de werkelijke oorzaak.

Ten tweede, en steeds belangrijker, speelt softwarebeveiliging een rol. Vrijwel alle moderne software bestaat voor een groot deel uit bestaande, door anderen geschreven bouwstenen die via online registers zoals PyPI (voor Python) of npm (voor JavaScript) worden gedownload. Dit netwerk van onderling afhankelijke bouwstenen heet de softwaresupplyketen. Als een aanvaller erin slaagt om, via een naamsverwarring, zijn eigen kwaadaardige bouwsteen te laten importeren in plaats van de bedoelde, legitieme bouwsteen, kan die aanvaller in potentie duizenden systemen tegelijk infecteren. Het beheersen van module shadowing is dus ook een kwestie van vertrouwen in de hele keten van software waarop bedrijven en overheden steunen.

Voorbeelden uit de praktijk

Het onderwerp is verre van theoretisch. Een aantal concrete gevallen laat zien hoe naamsverwarring tussen modules zich in de praktijk heeft ontwikkeld.

In 2021 publiceerde beveiligingsonderzoeker Alex Birsan zijn ontdekking van wat hij dependency confusion noemde: een aanvalstechniek waarbij hij publieke pakketten uploadde met dezelfde naam als interne, niet-openbare pakketten van grote bedrijven. Omdat veel installatiesystemen standaard voorrang geven aan het publieke register boven interne bronnen, downloadden de systemen van onder meer Apple, Microsoft, PayPal, Shopify, Netflix en Uber zonder het te weten Birsans (onschadelijke, voor onderzoeksdoeleinden gemaakte) bestanden in plaats van hun eigen interne code. Dit toonde aan hoe een naamsbotsing tussen modules op enorme schaal kan worden misbruikt.

Al veel eerder, in 2004, introduceerde de Python-gemeenschap PEP 328 (een "Python Enhancement Proposal", het formele voorstelproces voor taalwijzigingen), dat expliciete relatieve imports mogelijk maakte. Een van de motivaties was om programmeurs een duidelijkere manier te geven om aan te geven of ze een module uit hun eigen project bedoelden of een module uit de standaardbibliotheek, juist om onbedoelde overschaduwing te verminderen.

Ook buiten Python komt het probleem voor. In de statistische programmeertaal R overschaduwen functies als filter() en select() uit het populaire dplyr-pakket (onderdeel van de tidyverse-verzameling, ontwikkeld onder leiding van Hadley Wickham bij het bedrijf nu bekend als Posit) standaard gelijknamige functies uit R's ingebouwde stats-pakket. Dit verschijnsel heet in R-jargon "masking" en leidde tot herhaalde verwarring bij gebruikers. Als reactie ontwikkelde de r-lib-gemeenschap het pakket conflicted, dat programmeurs waarschuwt en dwingt een keuze te maken zodra twee geladen pakketten dezelfde functienaam gebruiken.

Het pakketregister npm voerde in 2015 scoped packages in: een systeem waarbij pakketten een voorvoegsel krijgen zoals @bedrijfsnaam/pakketnaam, zodat verschillende partijen niet langer om dezelfde, ongescheiden naamruimte hoeven te concurreren. Dit verkleinde het risico dat twee onafhankelijke pakketten toevallig identiek heten.

Een recenter en nog volop in ontwikkeling zijnd fenomeen is wat sommige beveiligingsonderzoekers "package hallucination" of "slopsquatting" noemen: AI-codeassistenten die tekst genereren alsof een bepaald softwarepakket bestaat, terwijl dat in werkelijkheid niet zo is. Onderzoek uit 2024 naar meerdere grote taalmodellen liet zien dat een aanzienlijk deel van de door AI voorgestelde pakketnamen niet daadwerkelijk bestond. Kwaadwillenden kunnen zulke verzonnen namen vervolgens zelf claimen op registers als PyPI of npm en er malware in plaatsen, in de hoop dat argeloze ontwikkelaars de AI-suggestie zonder controle overnemen. Dit is een jong onderzoeksgebied; de exacte omvang van het risico in de praktijk (hoeveel ontwikkelaars dit daadwerkelijk slachtoffer maakt) is nog niet goed in kaart gebracht en verdient meer onderzoek.

Hoe ver is de techniek?

Module shadowing zelf is geen nieuwe technologie die "uitontwikkeld" moet worden, maar een structureel kenmerk van hoe de meeste programmeertalen werken. De aandacht ligt daarom vooral op het beperken van de risico's, en op dat vlak is de afgelopen twintig jaar duidelijk vooruitgang geboekt.

Moderne ontwikkelomgevingen gebruiken linters — hulpprogramma's die code controleren op veelvoorkomende fouten nog voordat die wordt uitgevoerd. Populaire Python-linters zoals pylint en flake8 geven bijvoorbeeld een waarschuwing ("redefined-outer-name") als een naam een bestaande naam dreigt te overschaduwen. In de JavaScript-wereld kent de veelgebruikte linter ESLint een vergelijkbare regel, no-shadow.

Op het niveau van pakketregisters is er ook vooruitgang: PyPI werkt aan zogeheten Trusted Publishing, een systeem waarmee de herkomst van een pakket cryptografisch beter te verifiëren is, en npm biedt geautomatiseerde controles ("npm audit") op bekende kwetsbaarheden en verdachte pakketten.

Toch is het probleem niet opgelost. Naarmate meer code met hulp van AI wordt geschreven, verschuift het risico deels van menselijke vergissingen naar machinaal gegenereerde suggesties, en de bestaande verdedigingslinies zijn daar nog niet volledig op ingericht. Beveiligingsonderzoekers beschouwen dit dan ook als een actief, nog volop in ontwikkeling zijnd aandachtsgebied binnen softwarebeveiliging, niet als een afgerond hoofdstuk.

Wie werken eraan?

Verschillende partijen dragen bij aan het begrijpen en beperken van module shadowing en de bijbehorende beveiligingsrisico's. De Python Software Foundation, de non-profitorganisatie achter de programmeertaal Python, en het bijbehorende pakketregister PyPI werken doorlopend aan technische maatregelen en aan bewustwording binnen de gemeenschap. Aan de JavaScript-kant doet npm, Inc. (tegenwoordig onderdeel van GitHub, dat weer bij Microsoft hoort) hetzelfde voor het npm-register.

Op het gebied van bredere softwarebeveiliging speelt OWASP (Open Worldwide Application Security Project), een internationale non-profitgemeenschap van beveiligingsexperts, een rol door risico's rond de softwaresupplyketen te documenteren en te classificeren. De Open Source Security Foundation (OpenSSF), een samenwerkingsverband van grote techbedrijven onder de paraplu van de Linux Foundation, zet zich in voor bredere standaarden en hulpmiddelen om opensourcesoftware veiliger te maken.

Individuele onderzoekers hebben eveneens een zichtbare rol gespeeld: Alex Birsan bracht dependency confusion breed onder de aandacht, en beveiligingsbedrijf Socket.dev, mede opgericht door ontwikkelaar Feross Aboukhadijeh, publiceert regelmatig onderzoek naar kwaadaardige pakketten en nieuwe misbruikpatronen in open source-registers. Ten slotte houden de onderhoudsteams van linters zoals ESLint en Pylint de praktische, dagelijkse verdedigingslinie op orde voor miljoenen programmeurs wereldwijd.

Verder lezen