De software supply chain: waar vertrouwen de aanvalsvector wordt

Door Tom Kluter

De software supply chain: waar vertrouwen de aanvalsvector wordt

Organisaties investeren aanzienlijk in het beveiligen van hun infrastructuur en applicaties. Toch blijft één aanvalsvector structureel onderbelicht: de software supply chain. Aanvallers richten zich steeds vaker niet op de systemen zelf, maar op de bouwstenen waaruit software is opgebouwd. In het bijzonder de open-source packages, CI/CD-pipelines en developertooling waarop dagelijks wordt vertrouwd.

Het patroon in de software supply chain incidenten van het afgelopen jaar is opvallend consistent: niet één van deze aanvallen misbruikte een kwetsbaarheid in de code. Ze misbruikten allemaal een vertrouwensrelatie.

Recente incidenten illustreren de dreiging

Axios (Maart 2026). Een aanvaller compromitteerde het npm-account van de hoofdmaintainer van axios (een HTTP-client met ruim 100 miljoen downloads per week) en publiceerde twee malafide releases (1.14.1 en 0.30.4). De kwaadaardige code zat niet in axios zelf: beide versies voegde een phatom dependency toe: plain-crypto-js, een typosquat van crypto-js die nergens in de axios-broncode wordt geïmporteerd. Tijdens de installatie haalde die dependency een cross-platform Remote Access Trojan binnen voor Windows, macOS en Linux

Shai-Hulud en Miasma (2025–2026). The Shai-hulud-campagne toonde aan hoe aanvallers veelgebruikte npm-packages compromitteerden om malafide code te distribueren via installation scripts. De opvolger, de Miasma-worm, omzeilde de registries volledig. Op 5 juni 2026 schakelde GitHub binnen twee minuten 73 repositories uit in vier Microsoft-organisaties, nadat via een eerder gecompromitteerd contributor-account een malafide commit was gepusht naar Azure/durabletask.

De worm plaatste configuratiebestanden voor AI-coding agents (.claude/settings.json, .gemini/settings.json, Cursor- en VS Code-configuraties) die een credential-harvesting payload uitvoeren zodra een developer de repository lokaal opent.

Miasma introduceerde daarnaast een techniek die de standaardmitigatie ondermijnt: een klein binding.gyp-bestand triggerde een automatische node-gyp rebuild tijdens npm install, zonder lifecycle-script in package.json en zónder dat –ignore-scripts beschermde.

Het Nationaal Cyber Security Centrum (NCSC) heeft developers expliciet gewaarschuwd voor de risico’s van gecompromitteerde software-packages en benadrukt dat dit een serieuze bedreiging vormt voor Nederlandse organisaties. [1, 2]

Risico’s in package-ecosystemen

Package registries als npm en PyPI zijn gebaseerd op een model van openheid en vertrouwen. Dat maakt ze kwetsbaar voor verschillende aanvallen waaronder:

  • Typosquatting: packages met namen die sterk lijken op de die van populaire libraries.
  • Dependency confusion: het publiceren van een malafide package op een openbare registry met exact dezelfde naam als een interne package, maar met een hoger versienummer, waardoor pipelines de malafide variant binnentrekken.
  • Maintainer hijacking: het overnemen van een bestaand developer-account via gestolen sessies of credentials (bij axios begon dit met een gerichte social-engineeringcampagne tegen de maintainer, weken vóór de publicatie).
  • Malafide installation scripts: code (preinstall/postinstall) die direct wordt uitgevoerd tijdens installatie, nog vóór de applicatie zelf opgestart is (er bestaan inmiddels varianten die geen lifecycle-script nodig hebben, zoals de beschreven node-gyp-route).

Aanbevolen maatregelen: packages en pipelines

Pin op wat onveranderlijk is
Hier is onderscheid nodig tussen twee verschillende soorten afhankelijkheden.

Voor CI/CD-workflows (bijvoorbeeld GitHub Actions) geldt: pin op de commit-SHA (hash), niet op de versietag. Tags zijn muteerbaar, een aanvaller met schrijfrechten kan v4 naar een andere commit laten wijzen zonder dat iemand het merkt.

# Niet:
uses: actions/checkout@v4

# Wel de volledige commit-SHA, met de versie als comment:
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

Voor packages bestaat commit-hash-pinning niet. Daar is de lockfile met integrity hashes het equivalent. Cruciaal is dat de gebruikte build de lockfile daadwerkelijk respecteert:

# npm: gebruik npm ci in pipelines, niet npm install.
# npm ci installeert exact wat in package-lock.json staat, faalt bij afwijkingen.
npm ci

# pip: expliciete hash-verificatie afdwingen. Genereer het bestand met:
#   pip-compile --generate-hashes requirements.in
# en installeer met --require-hashes, zodat pip weigert bij ontbrekende hashes:
pip install --require-hashes [RN1] -r requirements.txt

Omdat de beheerlast van deze procedures snel kan oplopen, is het aan te raden om dit met behulp van geautomatiseerde tools zoals Dependabot or Renovate te doen. Deze tools controleren en updaten de gepinde hashes automatisch via Pull Requests. De security voordelen zijn zo gewaarborgd zonder de bijkomstige beheerlast.

Blokkeer pre- en post-installatie scripts

Installatie scripts zijn jarenlang een veelgebruikt aanvalspad geweest. Gelukkig lijken de package ecosystemen hier steeds beter maatregelen voor te treffen. Zo blokkeert pnpm de lifecycle scripts standaard sinds v10 [3], waarna ook npm in v12 [4] volgde. Ook impliciete node-gyp builds, git-dependencies en dependencies vanaf remote URL’s worden nu standaard geweigerd (waar bij het Miasma incident misbruik van werd gemaakt).

# Eenmalige blokkade lifecyle scripts per install:
npm install --ignore-scripts

# Permanent, via .npmrc (npm v11 en ouder):
ignore-scripts=true

# Of permanente ‘harde’ blokkade via de CLI: 
npm config set ignore-scripts true
	
# npm v12: expliciet goedkeuren wat wél mag draaien.
# De allowlist komt in package.json en hoort in versiebeheer.
npm approve-scripts --allow-scripts-pending

Neem deze wijziging wel met enige voorzichtigheid, projecten met native modules (bcrypt, sqlite3, grpc) breken zonder goedgekeurde allowlist.

Configureer een cooldown-periode

Nieuw gepubliceerde versies zijn het risicovolst in de eerste 24 tot 72 uur na release, de malafide axios-versies stonden nog geen drie uur online voordat de community ze detecteerde. Door een cooldown af te dwingen, worden nieuwe versies pas opgehaald nadat die tijd is verstreken.

// renovate.json
// let op: minimumReleaseAge is een string, en de packageRule
// heeft een match-selector nodig, anders wordt de config afgekeurd.
{

  "packageRules": [

    {

      "matchDatasources": ["npm"],

      "minimumReleaseAge": "3 days",

      "internalChecksFilter": "strict"

    }

  ],

  // Beveiligingsfixes moeten niet worden vertraagd:

  "vulnerabilityAlerts": { "minimumReleaseAge": "0 days" }

}

Sinds Renovate 42 wordt dit voor npm standaard afgedwongen via de preset security:minimumReleaseAgeNpm [5], controleer of die in de gebruikte configuratie actief is alvorens deze handmatig, dubbel te configureren.

# pyproject.toml
# vereist uv 0.9.17 of nieuwer

[tool.uv]

# Sluit packages uit die korter dan 3 dagen geleden zijn gepubliceerd:

exclude-newer = "3 days"

# Uitzondering voor een urgente securityfix:

exclude-newer-package = { cryptography = false }

Ook Dependabot hanteert sinds kort een cooldown-periode van drie dagen. Net als bij Renovate geldt dit alleen voor nieuwe versies en worden beveiligingsupdates wel direct verwerkt [6].

Beheers het aanvoerpunt: een interne registry

Een andere maatregel die veel impact heeft is het opzetten van een interne registry. Laat developers en pipelines niet rechtstreeks van npmjs.com of PyPI installeren, maar via een interne proxy of mirror (Artifactory, Nexus, Verdaccio). Dit levert meerdere voordelen op: één plek waar scanning, cooldown en allowlisting worden afgedwongen, bescherming tegen dependency confusion doordat interne namespaces voorrang krijgen, en een volledig auditspoor van de package activiteit.

Bescherm publish-credentials

Het axios-incident laat zien waar de echte grens ligt: de registry accepteert een geldig token als enige autorisatie. Geen enkele upstream-hardening compenseert een gelekt token.

  • Gebruik Trusted Publishing (OIDC) voor eigen packages, zodat er geen langlevend token bestaat om te stelen.
  • Verwijder publish-tokens zodra OIDC werkt. Een ongebruikte token blijft een geldige token.
  • Dwing phishing-bestendige MFA af op accounts met publiceerrechten.
  • Monitor op afwijkingen bij maintainer-accounts, bij axios was een aangepast emailadres de eerste zichtbare stap van de aanvaller.

Scansoftware integreren in CI/CD

Om malafide updates te detecteren, moet de pipeline zelf beveiligd zijn. Gebruik tools zoals Zizmor (linter voor GitHub Actions) of StepSecurity harden-runner, die het netwerkverkeer van de build-runners monitort en onverwachte uitgaande verbindingen blokkeert. Voeg daarnaast een EDR-oplossing toe op de build-nodes om processen op OS-niveau te analyseren op afwijkend gedrag.

Monitoring en detectie

Integreer telemetrie uit developer- en productieomgevingen in een bestaande SIEM-oplossing en trigger alerts op onder andere:

  • Onverwachte of niet-geautoriseerde versiewijzigingen.
  • Indicators of Compromise (IOC’s) geassocieerd met malafide packages.
  • Afwijkend netwerkverkeer vanuit de build- of developeromgevingen.
Figuur 1: Package activiteit op één host, potentiële typosquatting, dependency confusion, of targeted implants

De IDE als aanvalsoppervlak

Naast de registries is de Integrated Development Environment (IDE) een onderbelicht aspect van de developeromgeving. Extensies draaien met de rechten van de ingelogde developer en hebben daarmee volledige toegang tot het onderliggende systeem, de broncode en de lokaal opgeslagen credentials.

Hoe reëel dat risico is, bleek al in mei 2024, toen onderzoekers een nepextensie ‘Darcula’ publiceerden [7] (een typosquat van het populaire Dracula Official-thema). Binnen één dag was de extensie geïnstalleerd bij ruim honderd organisaties, waaronder een beursgenoteerd bedrijf met een marktwaarde van honderden miljarden en een landelijk rechtbanknetwerk.

Bijzonder was dat de onderzoekers de status van Verified Publisher verkregen op de marketplacedoor simpelweg het domein darculatheme.com te registreren. Dit bewees uitsluitend dat zij een domein bezaten, niet dat de extensie veilig was.

Aanbevolen maatregelen: developeromgeving

Centraal beheer via allow- en blocklists

Via VSCode enterprise policies kunnen beheerders de installatie van extensies centraal reguleren. Beheer is mogelijk via een Mobile Device Management (MDM) oplossing zoals MS Intune. Een allowlist van goedgekeurde publishers en extensies voorkomt ongecontroleerde installaties. Publiceer een allowlist via ADMX/ADML templates:

// VSCode Enterprise policies via MDM

<!-- Example: Allow extensions from specific publishers -->

<key>AllowedExtensions</key>

<string>{"microsoft": true, "github": true}</string>

<!-- Example: Set update mode to a specific value -->

<key>UpdateMode</key>

<string>start</string>

Voor organisaties met zwaardere security-eisen is een private marketplace het volgende niveau: extensies worden zelf gehost en geverifieerd voordat ze beschikbaar komen.

Beperk de rechten van AI-agents in de IDE

Configuratiebestanden in een repository kunnen tool-uitvoering triggeren zodra een project wordt geopend. Overweeg via enterprise policies het automatisch goedkeuren van tools uit te schakelen (ChatToolsAutoApprove), MCP-integratie te beperken tot goedgekeurde servers, en tools van derde-partij-extensies te blokkeren. Neem daarnaast agent-configuratiebestanden (.claude/, .gemini/, .cursor/, mcp.json) op in code review.

Beperk tot geverifieerde publishers

De VSCode Marketplace maakt onderscheid tussen reguliere developers en geverifieerde uitgevers. Door binnen de enterprise policies uitsluitend extensies toe te staan van Verified Publishers (gemarkeerd met het blauwe verificatievinkje), is er in ieder geval de zekerheid dat Microsoft de identiteit van de achterliggende publishers heeft gevalideerd

Zoals het Darcula-incident aantoonde, is dit geen waterdicht keurmerk. Verificatie bevestigt de identiteit, niet de integriteit van de code. Beschouw het blauwe vinkje daarom als een absolute ondergrens (een signaal), maar laat het nooit de enige controle zijn.

Cooldown-periode en versiebeheer

Consistent met het beleid voor package managers is het voor extensies ook aan te raden een cooldown-periode te configureren. Nieuwe updates van extensies moeten niet direct blind en automatisch naar de systemen van developers worden gepusht. Door updates centraal te reguleren en een vertraging van enkele dagen in te bouwen, wordt voorkomen dat een supply-chain aanval op een extensie direct impact heeft op de organisatie.

Monitoring en detectie

Zorg voor een EDR-oplossing die afwijkend gedrag van de IDE en geïnstalleerde extensies detecteert, en integreer die telemetrie in de SIEM. Hou er rekening mee dat veel securitytools de IDE als vertrouwd proces behandelen, wat malafide extensies juist dekking geeft. Controleer of deze uitzonderingen op developermachines niet te ruim staan. Trigger alerts op onder andere:

  • Onverwachte of niet-geautoriseerde processen doe worden gestart vanuit de IDE (bijvoorbeeld het uitlezen van SSH-keys of cloud-credentialbestanden).
  • Indicators of Compromise (IOC’s) geassocieerd met malafide extensies of aangetaste projectbestanden.
  • Afwijkend netwerkverkeer vanuit de IDE naar onbekende IP-adressen of domeinen.
Figuur 2: Externe netwerkverbindingen afkomstig van IDE’s.

Wanneer het toch misgaat

De cooldown van drie dagen helpt niet als iemand net in dat venster van drie uur installeerde. Zorg daarom dat de response stappen vooraf vaststaan:

  • Bepaal via lockfiles en build-logs welke machines en pipelines de betreffende versie daadwerkelijk hebben opgehaald en in welk tijdvenster.
  • Behandel elk getroffen systeem als gecompromitteerd, niet als “mogelijk geraakt”.
  • Roteer alles waar het betreffende systeem bij kon: cloud-credentials, registry-tokens, SSH-keys, CI/CD-secrets.
  • Pin naar een bekend schone versie en verifieer de integrity-hash in de lockfile.

Conclusie

Supply-chain aanvallen zijn effectief omdat ze vertrouwen als aanvalsvector gebruiken: vertrouwen in een maintainer, in een registry, in een gedeelde workflow, en sinds kort in een AI-agent die een repository opent. Geen enkele losse maatregel dekt dat af; pinning helpt niet tegen een gekaapt account, een cooldown niet tegen een worm die de registry overslaat, en pipeline-hardening niet tegen een gelekt publish-token.

Wat wel werkt, is gelaagdheid: het aanvoerpunt beheersen, uitvoering standaard weigeren, vertraging inbouwen en aannemen dat detectie te laat komt.

Weten hoe uw organisatie ervoor staat? In een assessment van één dag brengen we het dependency-beleid, pipeline-configuratie en IDE-beheer in kaart en toetsen we die aan de maatregelen uit dit artikel. U ontvangt een rapport met bevindingen en een gefaseerd implementatieplan.

Nu een incident? Ons incident-response team staat 24/7 paraat. Wij helpen bij het bepalen van de impact, het roteren van gecompromitteerde credentials en het herstellen van de integriteit van uw builds.


Dit onderzoek is uitgevoerd & geschreven door Tom Kluter:

Tom Kluter
Security Analyst

Sources:

[1] https://www.ncsc.nl/alerts/ontwikkelaars-opgelet-gecompromitteerde-npm-en-python-packages

[2] https://www.ncsc.nl/toeleveringsketen/omgaan-met-risicos-de-toeleveringsketen

[3] https://pnpm.io/supply-chain-security

[4] https://github.blog/changelog/2026-06-09-upcoming-breaking-changes-for-npm-v12/

[5] https://docs.renovatebot.com/presets-security/#securityminimumreleaseagenpm

[6] https://github.blog/security/supply-chain-security/the-case-for-a-cooldown-why-dependabot-now-waits-before-issuing-version-updates/

[7] https://www.koi.ai/blog/1-6-how-we-hacked-multi-billion-dollar-companies-in-30-minutes-using-a-fake-vscode-extension


 

Andere interessante links: