Subresource Integrity (SRI) is een W3C-beveiligingsstandaard waarmee je een cryptografische hash kunt opgeven op <script>- en <link>-tags, zodat de browser kan verifiëren dat het geladen bestand overeenkomt met wat je verwacht. Als het bestand op de URL is gewijzigd, onderschept of vervangen (door een aanvaller, een gecompromitteerd CDN, of zelfs door een accidentele update), blokkeert de browser de uitvoering volledig. SRI is gestandaardiseerd in 2016 en wordt ondersteund door elke grote browser. Het is een van de goedkoopste mitigaties tegen supply-chain-aanvallen op third-party JavaScript, wat in 2026 de dominante bron van inbreukincidenten op WordPress-sites is.
Hoe ziet een SRI-hash eruit, en hoe voeg ik hem toe?
Een script-tag met SRI-ingeschakeld heeft twee extra attributen: integrity en crossorigin:
<script
src="https://cdn.example.com/jquery-3.7.1.min.js"
integrity="sha384-1H217gwSVyLSIfaLxHbE7dRb3v4mYCKbpQvzx0cegeju1MVsGrX5xXxAvs/HgeFs"
crossorigin="anonymous">
</script>De integrity-waarde is een base64-gecodeerde cryptografische hash van de bestandsinhoud, voorafgegaan door het gebruikte algoritme (sha256-, sha384-, of sha512-). SHA-384 is de aanbevolen keuze in 2026: een goede balans tussen beveiliging en hash-lengte. SHA-512 is ook acceptabel. SHA-256 werkt nog, maar wordt beschouwd als de zwakste van de drie; prima voor niet-kritieke assets maar niet voor iets veiligheidsgevoeligs.
Wanneer de browser het bestand laadt, berekent hij de hash ervan en vergelijkt deze met de integrity-waarde. Komen de hashes overeen, dan draait het script. Verschillen ze ook maar één byte, dan weigert de browser het uit te voeren en logt een fout in de console.
Welke aanvallen voorkomt Subresource Integrity?
SRI beschermt specifiek tegen het geval waarin een third-party bestand wordt gewijzigd tussen het moment waarop je besloot het te vertrouwen en het moment waarop een browser van een gebruiker het daadwerkelijk laadt. De drie meest relevante scenario's voor WordPress-sites:
- CDN-compromittering. Als een aanvaller inbreekt in een CDN (of bij de third-party dienst wiens CDN je gebruikt) en een JavaScript-bestand wijzigt, zou elke site die dat bestand via
<script src>embedt plotseling de code van de aanvaller draaien. SRI vangt dit direct: het gewijzigde bestand komt niet overeen met de hash, de browser blokkeert het. - Account-overname bij de third-party provider. Iemand compromitteert een analytics-, chatwidget- of font-hosting-account en pusht een kwaadaardige update naar het script dat jij hebt geëmbed. Zonder SRI draait je site de kwaadaardige update bij elke pagelaad. Met SRI faalt het script stil totdat je de hash bijwerkt, wat betekent totdat je de nieuwe versie persoonlijk opnieuw hebt geëvalueerd.
- Netwerk-niveau manipulatie. Een man-in-the-middle-aanvaller op een bedrijfsnetwerk of vijandige WiFi herschrijft een JavaScript-bestand terwijl het naar de gebruiker transiteert. HTTPS voorkomt dit voor directe verbindingen naar je origin, maar een third-party script geserveerd via een door de aanvaller gecontroleerde DNS-poisoning-poging zou dat kunnen omzeilen. SRI biedt een end-to-end integriteitscontrole onafhankelijk van TLS.
De inbreuk bij British Airways in 2018 waarbij 380.000 klanten hun betalingsgegevens werden gestolen, gebeurde omdat de aanvaller een third-party Modernizr-script wijzigde dat BA op hun checkoutpagina laadde. SRI op die script-tag had de aanval gestopt op het moment dat het gewijzigde bestand laadde. Soortgelijke incidenten blijven gebeuren, met Magecart-stijl aanvallen op e-commerce-sites als de best gedocumenteerde categorie.
Aan welke bestanden moet ik SRI toevoegen?
SRI is voor third-party bestanden die over het netwerk worden geladen. Drie categorieën tellen, in prioriteitsvolgorde:
- Betalings-, checkout- en login-flows. Elke JavaScript die draait op een pagina waar gebruikers creditcards, wachtwoorden of andere gevoelige gegevens invoeren, is het hoogste-prioriteits doel. Een gecompromitteerd script op een checkoutpagina is het worst-case scenario. Als je WooCommerce-checkout iets vanaf een CDN laadt, zou elk van die scripts SRI moeten hebben.
- Globaal geëmbedde scripts. Alles in
<head>of bovenaan<body>dat op elke pagina draait: analytics-tags, fonts, polyfills, jQuery vanaf een publieke CDN. Deze draaien voordat de gebruiker de kans heeft iets verkeerds op te merken. - Plugin-geïnjecteerde CDN-scripts. Veel WordPress-plugins (chatwidgets, A/B-testing, marketingpixels) laden remote JavaScript. Deze zijn geschreven door third parties die je impliciet hebt vertrouwd, en bevatten doorgaans geen SRI standaard.
Andersom, voeg geen SRI toe aan bestanden die vanaf je eigen domein worden geserveerd. Als een aanvaller toegang heeft om bestanden op je origin-server te wijzigen, kan hij ook het HTML wijzigen dat de hash declareert, dus SRI biedt geen echte bescherming. SRI schittert alleen voor cross-origin resources.
Hoe genereer ik een SRI-hash voor een third-party script?
Drie praktische methoden:
- Gebruik srihash.org. Webgebaseerd tool. Plak de script-URL, krijg de volledige
<script>-tag terug met integrity- en crossorigin-attributen. Snelste pad voor losse toevoegingen. - OpenSSL op de commandoregel.
curl -s https://cdn.example.com/file.js | openssl dgst -sha384 -binary | openssl base64 -Ageeft de base64-hash uit waar jesha384-voor zet. Nuttig bij scripting of werken met lokale bestanden vóór deployment. - Controleer de documentatie van de provider. Grote CDNs (cdnjs.com, jsDelivr) publiceren de SRI-hash naast elke versie van elke library die ze hosten. Bootstrap, jQuery, Vue, React, etc. publiceren allemaal de aanbevolen integrity-waarde op hun officiële getting-started pagina's. Kopieer-plak vandaar.
Eén voorbehoud: de hash is gebonden aan de exacte byte-inhoud van het bestand. Als het CDN een andere versie serveert (omdat je een URL als jquery@3 hebt gebruikt in plaats van jquery@3.7.1), komt de hash niet overeen en wordt het script geblokkeerd. Pin altijd op specifieke versies bij gebruik van SRI.
Waarom is het crossorigin="anonymous"-attribuut vereist?
Het crossorigin="anonymous"-attribuut vertelt de browser het third-party bestand op te halen met CORS, zonder cookies of authenticatie te sturen. Zonder dit kan de browser de response body van het bestand niet lezen om de hash te berekenen (een eigenaardigheid van het same-origin policy), en de SRI-verificatie faalt stilletjes open: het script draait zonder gecontroleerd te worden.
Dit is de meest voorkomende SRI-fout. Mensen voegen integrity toe maar vergeten crossorigin, en gaan er dan vanuit dat hun setup werkt omdat het script blijft laden. Zonder beide attributen heb je geen echte bescherming. Om te verifiëren: open DevTools, Network-tab, klik op het script, kijk naar de response. Als het CDN CORS ondersteunt (vrijwel alle moderne publieke CDNs doen dat), zie je Access-Control-Allow-Origin: * in de response headers. Zonder die header kan SRI helemaal niet werken op die resource.
Hoe voeg ik SRI toe in WordPress?
Drie scenario's afhankelijk van hoe scripts in je pagina's komen:
Scenario 1: scripts enqueued door WordPress (theme of plugin)
WordPress-core ondersteunt SRI via het script_loader_tag-filter. Voeg toe aan de functions.php van je child theme of een klein mu-plugin:
add_filter('script_loader_tag', function ($tag, $handle, $src) {
$sri_hashes = [
'jquery' => 'sha384-1H217gwSVyLSIfaLxHbE7dRb3v4mYCKbpQvzx0cegeju1MVsGrX5xXxAvs/HgeFs',
'bootstrap' => 'sha384-...jouw-hash-hier...',
];
if (isset($sri_hashes[$handle]) && strpos($src, '://') !== false && strpos($src, home_url()) === false) {
$tag = str_replace(
' src=',
' integrity="' . $sri_hashes[$handle] . '" crossorigin="anonymous" src=',
$tag
);
}
return $tag;
}, 10, 3);Pas de handle-namen en hashes aan om bij je scripts te passen. De strpos-checks zorgen ervoor dat SRI alleen wordt toegepast op scripts die vanaf externe domeinen worden geladen, niet vanaf je eigen.
Scenario 2: scripts hardcoded in theme-templates
Als een theme rechtstreeks <script src="https://...">-tags in header.php of elders uitvoert, bewerk die tags direct om de integrity- en crossorigin-attributen toe te voegen. Spiegel dit in je child theme om parent theme-updates te overleven.
Scenario 3: scripts geïnjecteerd door JavaScript of third-party plugins tijdens runtime
Chatwidgets, A/B-testtools en tagmanagers injecteren script-tags vaak dynamisch. SRI werkt ook in dit geval: het dynamisch gecreëerde <script>-element moet de integrity- en crossOrigin-properties instellen voordat het script aan de DOM wordt toegevoegd. De meeste enterprise-versies van deze tools ondersteunen dit via configuratie; de gratis tiers doorgaans niet. Voor onbeheerde third-party-injecties is de praktische terugval een Content Security Policy met require-sri-for script (nog in concept) of gewoon zorgvuldige auditing.
Wat is de onderhoudslast van SRI?
Dit is de eerlijke trade-off. SRI is een afweging tussen beveiliging en gemak. Elke keer dat de upstream-library wordt bijgewerkt, verandert de hash, breekt je script, en moet je de hash bijwerken. Voor een stabiele site die versies pint en ze zelden bijwerkt, is dit een eens-per-kwartaal taak. Voor een site die jquery@latest gebruikt of vertrouwt op auto-updatende CDNs, is SRI een constante bron van breuken.
Drie patronen die SRI-onderhoud behapbaar maken:
- Pin op specifieke versies, niet "latest". URL als
https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js, nietjquery@latest. De hash is dan stabiel totdat je bewust upgradet. - Gebruik een CDN dat hashes publiceert. cdnjs en jsDelivr publiceren beide de SRI-hash voor elk bestand. De hash bijwerken bij een upgrade is een taak van 30 seconden.
- Self-host kritieke libraries. Zodra je self-host (wat je sowieso om GDPR-redenen zou moeten overwegen, zie de Google Fonts-discussie), wordt SRI irrelevant voor dat script. SRI is voor gevallen waarin je niet kunt self-hosten. Voor analytics, fonts, libraries gebruikt op één pagina, is self-hosting vaak het betere antwoord.
Veelvoorkomende fouten
crossorigin="anonymous"vergeten. Het script blijft laden maar wordt niet meer op integriteit gecontroleerd. De meest voorkomende stille SRI-fout.- SRI gebruiken op same-origin resources. Een aanvaller die je
/wp-includes/js/jquery.jskan wijzigen, kan ook het HTML wijzigen dat de hash declareert. Gebruik SRI alleen op cross-origin resources. - De hash berekenen op de verkeerde bestandsversie. De hash moet overeenkomen met de exacte bytes die de browser ontvangt, inclusief CDN-zijde minificatie of transformatie. Haal altijd op vanaf de werkelijke productie-URL bij het berekenen.
- De hash niet bijwerken bij library-upgrade. Upgrade de libraryversie in de URL, vergeet
integritybij te werken, het script werkt stil niet meer. Symptomen: een feature breekt, de console toont "Failed to find a valid digest in the integrity attribute". - SHA-1 gebruiken. SHA-1 is botsing-kwetsbaar en is voor SRI gedeprecateerd. Gebruik SHA-384 of SHA-512.
- SRI proberen op een CDN zonder CORS. De browser kan de hash niet berekenen, dus SRI is onmogelijk. Of het CDN moet CORS inschakelen, of je moet het bestand self-hosten.
SRI en Content Security Policy (CSP)
SRI en CSP zijn complementair, niet overbodig. CSP zegt "alleen scripts van deze lijst van origins mogen draaien". SRI zegt "en dat script moet overeenkomen met deze exacte hash". Samen vormen ze een defense-in-depth benadering: CSP blokkeert onbekende origins; SRI blokkeert manipulatie aan bekende origins. Een CSP met script-src 'self' https://trusted-cdn.com zegt "we vertrouwen trusted-cdn.com"; SRI-hashes toevoegen aan je scripts op trusted-cdn.com vernauwt dat vertrouwen tot specifieke bestandsversies.
De concept-CSP-directieve require-sri-for script zou afdwingen dat elk cross-origin-script een integrity-attribuut moet hebben, op browserniveau. Per 2026 heeft het beperkte ondersteuning maar het is de richting waar de standaard heen beweegt.
Wat InspectWP controleert
De Security-sectie van elk InspectWP-rapport inspecteert externe script- en stylesheet-tags en meldt welke integrity-attributen bevatten en welke niet. Ontbrekend SRI op een script vanaf een third-party CDN wordt gemarkeerd als bevinding van lage tot middelhoge ernst, afhankelijk van context. Een login- of checkoutpagina die externe JavaScript zonder SRI laadt is een waarschuwing met hogere prioriteit. Het rapport markeert ook misvormde integrity-waarden (verkeerd algoritme-voorvoegsel, ongeldige base64) die een vals gevoel van bescherming kunnen geven terwijl ze daadwerkelijk door de browser worden genegeerd. SRI is een van die maatregelen waarbij het bestaan van het attribuut minder telt dan de juistheid ervan; een verkeerde hash is functioneel gelijk aan geen hash omdat de browser mismatches nog steeds afwijst, maar een ontbrekend crossorigin-attribuut maakt de hele controle stil.