Eerst even: wat is een bouwsteen?
Een website bouw je niet helemaal vanaf nul. Voor veel dingen ligt er al code klaar die een ander heeft geschreven. Bijvoorbeeld om een foto kleiner te maken, om een pdf te maken of om met een andere site te praten. Zo'n kant-en-klaar stukje code noemen bouwers een pakket. Wij zeggen liever: een bouwsteen.
Die bouwstenen staan op grote verzamelplaatsen op internet. Iedereen mag ze gratis gebruiken. De twee bekendste:
- npm is de verzamelplaats voor JavaScript. Dat is de taal waarin de meeste scripts in je browser geschreven zijn, en veel sites gebruiken hem ook op de server.
- PyPI is de verzamelplaats voor Python. Dat is de taal waarin wij bouwen. Waarom, lees je in Waarom wij in Python bouwen.
Waarom gebruikt bijna elke site zulke bouwstenen? Omdat het slim is. Een bouwsteen die duizenden bouwers gebruiken, is vaak goed getest. Je hoeft het wiel niet opnieuw uit te vinden. Een site is daardoor sneller klaar en vaak ook beter.
Maar er zit een andere kant aan. Elke bouwsteen is code van iemand anders die op jouw server draait. Je vertrouwt er dus op dat die ander het goed doet.
Wat is een aanval via de toeleveringsketen?
Denk aan een fietsenmaker. Hij bouwt fietsen met onderdelen van verschillende leveranciers: remmen van de een, banden van de ander. Hij test de fiets en verkoopt hem. Maar stel dat een leverancier ongemerkt slechte remmen levert. Dan is de fiets onveilig, terwijl de fietsenmaker zelf niets fout deed.
Zo werkt een aanval via de toeleveringsketen. De inbreker valt niet jouw site aan, maar een leverancier van jouw site: de maker van een bouwsteen. Lukt dat, dan zet hij een nieuwe versie van die bouwsteen online met slechte code erin. Iedereen die daarna bijwerkt, haalt die slechte code binnen. Vaak zonder het te merken.
Dat maakt zo'n aanval lastig. Een inbreker hoeft maar één bouwsteen te raken om in één keer bij heel veel sites binnen te komen.
Wat was er aan de hand bij npm?
Op 13 oktober 2026 schreven onder meer Help Net Security en CSO Online, twee nieuwssites over beveiliging, over een fout in npm. Onderzoekers van het beveiligingsbedrijf Bloom Security hadden hem gevonden.
De fout zat in een functie die "Trusted Publishing" heet, in het Nederlands zoiets als "vertrouwd uitbrengen". Daarmee kan een bouwer een nieuwe versie van zijn bouwsteen online zetten zonder wachtwoord. npm vertrouwt dan een vaste plek op GitHub, een site waar bouwers hun code bewaren. Komt een nieuwe versie van die plek, dan mag hij online.
Het probleem: npm onthield die plek alleen bij naam. Volgens Bloom ging het zo:
- Een bouwer gaf zijn plek op GitHub een andere naam, gaf hem aan een ander of haalde hem weg.
- De oude naam kwam dan vrij. Iemand anders kon die naam claimen.
- npm vertrouwde de naam nog steeds. Wie de oude naam had, kon dus een nieuwe versie van de bouwsteen online zetten. Zonder een wachtwoord te stelen.
Vergelijk het met een bezorglijst bij de achterdeur van een winkel: "Leveringen van Bakkerij Jansen mogen naar binnen." Gaat Bakkerij Jansen weg en begint iemand anders een zaak onder die naam, dan staat die ook op de lijst.
Een paar feiten op een rij, volgens Help Net Security en CSO Online:
- Ruim 1.500 bouwstenen liepen risico. Samen waren ze meer dan 10 miljoen keer gedownload.
- Er is geen misbruik gezien. Bloom heeft niet gezien dat iemand de fout echt gebruikte. De onderzoekers probeerden het alleen uit op hun eigen bouwstenen. Of iemand anders het eerder deed, weet niemand zeker.
- Er is een reparatie. Volgens CSO Online bracht npm op 2 oktober 2026 een reparatie uit. Een instelling die niet binnen 48 uur wordt gebruikt, vervalt nu vanzelf.
- Makers moeten zelf nog kijken. Bloom raadt makers van bouwstenen aan na te gaan of elke plek die npm vertrouwt nog echt van hen is.
Bloom noemt de namen van de bouwstenen niet. Je kunt dus niet zelf opzoeken of jouw site er een gebruikte. Dat kan je bouwer wel voor je nagaan.
Niet de eerste keer dit jaar
Dit was geen losse gebeurtenis. Ook eerder in 2026 waren er aanvallen via bouwstenen, op npm en op PyPI. Twee voorbeelden:
- Axios op npm, maart 2026. Axios is een veelgebruikte bouwsteen om met andere sites te praten. Volgens InfoQ, een nieuwssite voor bouwers, wordt hij meer dan 100 miljoen keer per week gedownload. Op 31 maart zette een inbreker via een overgenomen account van een maker twee slechte versies online. Wie zijn bouwstenen liet meegroeien met de nieuwste versie, haalde de slechte code bij de volgende installatie vanzelf binnen.
- LiteLLM op PyPI, maart 2026. Dit is een Python-bouwsteen voor werken met AI. Volgens het beveiligingsbedrijf NetSPI werd op 24 maart het GitHub-account van een maker overgenomen. Er kwamen twee slechte versies online die wachtwoorden en sleutels van de computer stalen. Volgens NetSPI had de kant-en-klare versie van de makers zelf er geen last van, omdat die vaste versies gebruikt.
Valt je iets op? In beide gevallen liep vooral risico wie automatisch de nieuwste versie binnenhaalde. Wie een vaste versie gebruikte, liep minder risico. Daar komen we zo op terug.
Wat kun je vragen aan je bouwer?
Je hoeft zelf geen code te lezen om goede vragen te stellen. Een goede bouwer geeft op deze vragen gewoon antwoord:
- Hoeveel bouwstenen van anderen gebruikt mijn site? Een paar, of honderden? Weinig is niet vanzelf beter, maar wel overzichtelijker.
- Gebruikt mijn site npm? En zo ja: heb je nagekeken of er bouwstenen bij zitten die door dit lek geraakt kunnen zijn?
- Staan de versies vast? Of haalt de site vanzelf elke nieuwe versie binnen?
- Wie werkt de bouwstenen bij, en hoe vaak? En wordt er na het bijwerken getest?
- Laadt mijn site scripts of lettertypes van andere bedrijven? Elk bestand dat van een ander komt, is weer een leverancier die je moet vertrouwen.
- Is er een back-up? Gaat er toch iets mis, dan wil je terug kunnen.
Krijg je geen helder antwoord? Dan is dat geen ramp. Maar het is wel een goed moment om er samen eens rustig naar te kijken.
Hoe wij het doen
Wij gebruiken ook bouwstenen van anderen. Dat is slim, zoals hierboven staat. Maar we gaan er zuinig mee om. Zo houden we het risico klein:
- Weinig bouwstenen. We nemen alleen wat echt nodig is. Nummerbordcheck.nl gebruikt er drie: Flask, gunicorn en requests. Lichthoek ook drie: Flask, gunicorn en Pillow. broercollective.com draait op de standaardbibliotheek van Python, dus wat Python zelf al meebrengt, met een paar extra's voor pdf's en versleuteling.
- Vaste versies. Van de bouwstenen die we zelf kiezen, zetten we de versie vast. Een nieuwe versie komt niet vanzelf op onze sites, maar pas als wij een site opnieuw bouwen.
- Bewust bijwerken, en dan testen. We werken de bouwstenen bewust bij, in één keer. Daarna testen we of alles nog goed werkt. Pas dan gaat het live. De updates doen wij, je hoeft daar zelf niets voor te doen.
- Geen npm, en zuinig met scripts van anderen. In onze sites gebruiken we geen npm. De scripts in je browser schrijven we meestal zelf. Voor een kaart of een grafiek gebruiken we soms een bekend script van anderen, als vaste kopie op onze eigen server. Lettertypes komen van onze eigen server. Scripts van andere bedrijven alleen als het echt moet, zoals een controle tegen robots, en met je akkoord.
- Een eigen server in Europa. Onze server staat in een datacenter binnen de EU. Meer daarover lees je in Hosting in Europa en de AVG.
- Back-up en controle. Elke dag maken we een kopie van de gegevens. We houden in de gaten of alles draait, en grijpen in als het nodig is.
Laten we wel wezen: dit maakt het risico kleiner, niet nul. Ook een vaste versie van een bouwsteen kan een fout bevatten die pas later bekend wordt. Een bouwsteen gebruikt soms zelf ook weer andere bouwstenen. En bij het bijwerken halen we wel een nieuwe versie binnen. Daarom testen we na elke update. Hoe we je site verder bijhouden, lees je bij hosting en beheer.



