Software supply chain: Composer, npm en CI als ingang naar je webshop
Terug naar blog

Software supply chain: Composer, npm en CI als ingang naar je webshop

Bijgewerkt 8 min leestijd

Je webshop bestaat voor het grootste deel uit code die jij niet schreef. Wie die code, je pipeline en je deploy-rechten niet in de hand heeft, heeft de voordeur…

Je webshop bestaat voor het grootste deel uit code die jij niet schreef. Wie die code, je pipeline en je deploy-rechten niet in de hand heeft, heeft de voordeur open laten staan.

OWASP nam in de Top 10:2025 een nieuwe categorie op: A03 Software Supply Chain Failures. Dat past bij wat wij in de praktijk zien. Aanvallers breken niet altijd je shop binnen. Ze breken in bij iets waar je shop op vertrouwt: een package, een build-server, een token.

Dit artikel gaat over tooling en pipeline. Over de extensies zelf schreven we al Magento-extensies veilig installeren. Hier kijken we naar Composer, npm, CI en de vraag wie mag deployen.

Wat is een supply chain-aanval in een webshop?

Een supply chain-aanval gebruikt een vertrouwde schakel om binnen te komen. In een Magento-, Shopify- of Laravel-project zijn dat meestal:

  • een Composer-package of npm-package met kwaadaardige code
  • een package dat een bekende kwetsbaarheid bevat en nooit is geüpdatet
  • een build- of CI-omgeving waar secrets in staan
  • een account van een ontwikkelaar of leverancier dat is overgenomen
  • een package met een bijna-gelijke naam (typosquatting)

Het gemeenschappelijke probleem: de code draait met de rechten van je applicatie. Kwaadaardige code in een dependency kan je database lezen, orders aanpassen of een skimmer op de checkout zetten. Zie ook Magecart-skimmers detecteren en verwijderen.

Lockfiles: dit is je eerste verdedigingslinie

Een composer.lock legt vast welke exacte versies je installeert, inclusief de hash van de broncode. Een package-lock.json doet hetzelfde voor npm.

De regels zijn simpel:

  • Commit altijd composer.lock en package-lock.json.
  • Installeer op productie en in CI met composer install, nooit met composer update.
  • Gebruik npm ci in plaats van npm install. npm ci houdt zich strikt aan het lockfile en faalt als lockfile en package.json niet kloppen.
  • Review een wijziging in het lockfile als een codewijziging. Een pull request die 40 packages verandert, verdient aandacht.
bash
composer install --no-dev --prefer-dist --no-interaction --optimize-autoloader
npm ci --ignore-scripts

Over --ignore-scripts hieronder meer.

Wat doet composer update fout op productie? Het resolvet versies opnieuw. Je deployt dan code die niemand heeft getest, en soms code die nooit door review is gegaan. Dat is geen supply chain-beheer.

composer audit in CI

Sinds Composer 2.4 bestaat composer audit. Het vergelijkt je geïnstalleerde packages met bekende security advisories en geeft een niet-nul exitcode terug als er iets wordt gevonden.

bash
composer audit

Zet dit in je pipeline, zodat een kwetsbaar package de build breekt. Een paar praktische punten:

  • Draai het bij elke pull request én op een schema (dagelijks of wekelijks). Een package kan kwetsbaar worden zonder dat jij iets wijzigt.
  • Laat een gevonden advisory niet stilzwijgend door. Als je bewust een uitzondering maakt, leg dan vast waarom en tot wanneer.
  • Combineer het met npm audit voor je frontend-tooling, maar lees de uitkomst kritisch. Veel npm-meldingen gaan over build-tools die nooit op productie draaien. Dat is ruis, geen alarm.

Eerlijk is: composer audit vindt alleen bekende problemen. Een nieuw gecompromitteerd package vindt het niet. Het is een noodzakelijke basis, geen complete oplossing.

Gecompromitteerde packages en typosquatting

Er zijn twee veelvoorkomende scenario's.

Het overgenomen package. De maintainer verliest zijn account, of een nieuwe maintainer neemt een verlaten package over. Een volgende release bevat extra code. Wie blind update draait, haalt die binnen. Typosquatting. Iemand publiceert een package met een naam die lijkt op een bekend package. Eén typefout in composer require of npm install is genoeg.

Wat helpt:

  • Controleer bij elke nieuwe dependency de naam, de vendor, het aantal gebruikers en de bron. Kopieer de installatieregel uit de officiële documentatie, typ hem niet over.
  • Voeg niet lichtzinnig packages toe. Elke dependency is een stuk code dat je moet vertrouwen en bijhouden. Een kleine helper van 20 regels schrijf je beter zelf.
  • Kijk wat een package bij installatie uitvoert. Composer kent scripts (post-install-cmd en vergelijkbaar), npm kent postinstall. Daar zit een bekende ingang.
  • Gebruik npm ci --ignore-scripts in CI als je build dat toelaat, en sta alleen scripts toe voor de packages die ze echt nodig hebben.

Composer-plugins verdienen extra aandacht. Sinds Composer 2.2 moet je plugins expliciet toestaan via allow-plugins in composer.json. Behandel die lijst als een allowlist en voeg er niet zomaar iets aan toe.

Private repositories en sleutels: repo.magento.com en Hyvä

Magento-projecten halen packages binnen van repo.magento.com. Dat vraagt een public/private key-paar uit je Adobe Commerce-account. Voor Hyvä-licenties werkt het via een private Packagist-omgeving met een eigen token.

Die credentials staan vaak in een auth.json. Dat bestand is zo'n plek waar het fout gaat:

  • auth.json staat in de git-repository, waardoor de keys in de geschiedenis zitten.
  • Eén gedeeld key-paar op naam van een oud-medewerker of een externe partij.
  • Dezelfde keys op de laptop van elke ontwikkelaar, in CI én op productie.

Wat wij aanraden:

  • Houd auth.json buiten git (.gitignore) en geef CI de credentials via beveiligde variabelen.
  • Gebruik waar het kan een key-paar per omgeving of per doel, zodat je er één kunt intrekken zonder dat alles stilvalt.
  • Roteer de keys bij elk personeelsverloop aan jouw of onze kant, en na elk vermoeden van een lek.
  • Heb je auth.json ooit gecommit, behandel de keys dan als gelekt. Verwijderen uit de laatste commit is niet genoeg.
  • Draai composer install op productie niet vanaf een server waar die keys permanent staan. Bouw in CI, deploy het resultaat.

CI-secrets: de pipeline is een doelwit

Een CI-omgeving heeft vaak meer macht dan een ontwikkelaar: SSH-keys naar productie, database-wachtwoorden, API-tokens, Composer-keys. Wie de pipeline overneemt, krijgt dat allemaal.

Basisregels:

  • Geen secrets in de repository. Ook niet in een .env.example met echte waarden.
  • Minimale rechten per token. Een deploy-key hoeft niet naar alle servers te kunnen. Een read-only token volstaat voor het ophalen van packages.
  • Secrets alleen voor de jobs die ze nodig hebben. Een testjob voor een pull request van een externe contributor hoort geen deploy-credentials te zien.
  • Let op third-party actions en plugins in je CI. Pin ze op een vaste commit of versie in plaats van een bewegende tag zoals latest of main.
  • Logs zijn ook een lek. Zorg dat secrets worden gemaskeerd en dat een env-dump niet in je buildlog belandt.
  • Roteer. Een secret dat drie jaar ongewijzigd blijft, is vaak ook door drie oud-collega's gezien.

Gebruik waar mogelijk kortlevende credentials in plaats van permanente sleutels. Dat verkleint de schade als er toch iets lekt.

Wie mag deployen?

Dit is de vraag die we bij audits vaak als eerste stellen. De antwoorden zijn zelden netjes:

  • Meerdere mensen kunnen vanaf hun eigen laptop naar productie deployen.
  • Iedereen met schrijfrechten kan direct naar main pushen, en main deployt automatisch.
  • Een extern bureau heeft nog steeds SSH-toegang van een project dat vorig jaar eindigde.

Een bruikbare inrichting:

OnderdeelMinimale norm
Branch mainBeschermd, wijzigen alleen via pull request met review
Deploy naar productieAlleen vanuit CI, niet vanaf een laptop
GoedkeuringTweede persoon bij productie-deploys of bij wijzigingen aan de pipeline
Server-toegangPersoonlijke accounts, SSH-keys, geen gedeeld wachtwoord
Oud-medewerkers en leveranciersToegang direct intrekken, periodiek controleren
Wijzigingen aan .gitlab-ci.yml, workflows, composer.jsonAltijd review, want hier zit de macht

Bij een klein team is een strenge procedure geen reden om traag te zijn. Bij ons gaat een wijziging via een pull request, de ander kijkt mee, de pipeline draait de checks. Dat kost minuten.

Een supply chain-aanval herkennen

Je ziet het zelden aan een foutmelding. Let op:

  • onverwachte wijzigingen in composer.lock of package-lock.json zonder bijbehorende code
  • nieuwe of gewijzigde bestanden in vendor/ op productie, terwijl je via CI deployt
  • uitgaand verkeer vanaf je webserver naar onbekende domeinen
  • nieuwe JavaScript op de checkout die je niet kent
  • builds die ineens langer duren of andere netwerkverbindingen maken

Op productie is het handig om te controleren of vendor/ overeenkomt met wat je hebt gedeployd. Hoe je dat monitort lees je in security logging voor webshops en in ons incident response plan.

Wat is overkill?

Niet elke shop heeft een volledige SBOM-pijplijn en een eigen package-mirror nodig. Eerlijk gezegd levert dit al veel op:

  1. Lockfiles committen en install/ci gebruiken
  2. composer audit in CI
  3. auth.json en secrets buiten git
  4. Deployen alleen vanuit CI, met review op main
  5. Toegang opruimen bij vertrek

Een eigen mirror of strikte allowlist per package is pas zinvol bij grote, complexe projecten of strenge compliance-eisen. Voor een gemiddelde webshop met een handvol extensies is de bovenstaande lijst het verstandige begin.

Veelgestelde vragen

Is composer audit genoeg om mijn Magento-shop te beveiligen?

Nee. composer audit vergelijkt je packages met bekende advisories. Het vindt geen nieuw gecompromitteerd package en geen kwetsbaarheid in je eigen code. Het hoort bij een bredere aanpak met reviews, patches en monitoring.

Moet ik composer.lock committen in een Magento-project?

Ja. Het lockfile zorgt dat elke omgeving exact dezelfde versies krijgt. Zonder lockfile weet je niet meer wat er op productie draait en kun je een fout niet betrouwbaar reproduceren.

Wat doe ik als mijn auth.json ooit in git heeft gestaan?

Behandel de keys als gelekt. Maak nieuwe keys aan in je Adobe Commerce-account (of bij je Hyvä-licentie), trek de oude in en werk CI en servers bij. Het bestand verwijderen uit de laatste commit lost het niet op, want de geschiedenis blijft.

Hoe vaak moet ik dependencies updaten?

Security-updates zo snel mogelijk, de rest in een vaste cadans, bijvoorbeeld maandelijks. Kleine, regelmatige updates zijn veiliger en goedkoper dan één grote sprong na twee jaar. Zie ook onze Magento 2 security checklist.

Geldt dit ook voor Shopify?

Deels. Bij Shopify beheert Shopify het platform, maar apps, thema's en je eigen build-tooling (npm) blijven jouw verantwoordelijkheid. Wat Shopify wel en niet regelt staat in Shopify security: wat regelt Shopify, wat jij.

Wil je weten hoe jouw pipeline, dependencies en toegangsrechten ervoor staan? We bekijken het in een security audit en vertalen de bevindingen naar een lijst die je team zelf kunt afwerken. Neem contact op via /contact.

Ruthger Idema

Geschreven door Ruthger Idema

15+ jaar ervaring in e-commerce development. Gespecialiseerd in Magento, Shopify en Laravel maatwerk.

Meer over ons team →
Deel dit artikel:

Wil je jouw e-commerce naar het volgende niveau?

Plan een vrijblijvend gesprek met onze experts over Magento, Shopify of Laravel maatwerk.

Plan een Tech Check