Wie diese Prüfung funktioniert
Scanaris geht das HTML deiner Startseite durch und betrachtet zwei Arten von Tags: <script src="..."> und <link rel="stylesheet" href="...">. Jede URL wird gegen die der Seite aufgelöst und als extern betrachtet, wenn ihr Origin (Schema, Domain und Port) von deinem abweicht; das schließt URLs ein, die mit // beginnen und mit dem Protokoll der Seite vom CDN laden. data: und blob: werden ignoriert. Für jede externe Ressource wird geprüft, ob das Attribut integrity vorhanden ist; fehlt es, wird sie notiert. Gibt es mindestens eine, öffnet sie einen Befund mit niedrigem Schweregrad mit der Anzahl der Ressourcen und den ersten zehn URLs. Skripte und Styles von deiner eigenen Domain werden nicht gemeldet: Dort bringt SRI nichts.
Warum das wichtig ist
Lädst du eine Bibliothek von einem CDN, führst du im Browser deiner Nutzer aus, was dieses CDN zu liefern beschließt. Wird das CDN kompromittiert oder wechselt seine Domain den Besitzer, kann die Datei durch eine ersetzt werden, die dasselbe tut und zusätzlich Formulare stiehlt oder auf Betrugsseiten umleitet. Genau das passierte im Juni 2024 mit polyfill.io: Die Domain wurde verkauft, das Skript begann, bösartigen Code einzuschleusen, und über hunderttausend Seiten, die es einbanden, lieferten ihn aus, ohne es zu merken. Das Attribut integrity enthält den Hash der Datei, die du geprüft hast; der Browser hasht, was er herunterlädt, und führt es bei Abweichung nicht aus. Es ist niedriger Schweregrad, weil erst das CDN angegriffen werden muss, aber wenn das passiert, ist der Schaden total und still.
So behebst du es
Option 1: integrity an die Tags hängen
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"
integrity="sha384-..." crossorigin="anonymous"></script>
Den Hash bekommst du, indem du die exakte Datei herunterlädst und ausführst:
curl -s https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js | openssl dgst -sha384 -binary | openssl base64 -A
cdnjs und jsDelivr zeigen neben jeder Datei einen fertigen Hash zum Kopieren. Das Attribut crossorigin="anonymous" ist Pflicht, damit der Browser eine Ressource eines anderen Origins verifizieren kann. Und die URL muss auf eine fixe Version zeigen (@4.4.0), nie auf latest: Aktualisiert das CDN die Datei, passt der Hash nicht mehr und deine Seite lädt die Bibliothek nicht mehr, was bei einer ungeprüften Änderung genau das ist, was du willst.
Option 2: Bibliotheken von der eigenen Domain ausliefern
Installiere sie mit npm und lass deinen Bundler (Vite, webpack, Nuxt, Next.js) sie in deinen Build aufnehmen. Dann kommt die Datei von deinem Server, mit Hash im Namen, und SRI ist nicht mehr nötig. Das ist die übliche Wahl in modernen Projekten und die, die den Befund an der Wurzel löst.
Was kein SRI zulässt
Die Stylesheets von Google Fonts ändern sich je nach anfragendem Browser, ihr Hash ist also nicht stabil: Entweder akzeptierst du diesen Befund oder du hostest die Schriften selbst (was auch Datenschutz und Geschwindigkeit verbessert). Analyse- und Werbeskripte, die sich selbst aktualisieren (gtag.js, das Meta-Pixel), vertragen ebenfalls keinen festen Hash; dort ist die Verteidigung die CSP, die begrenzt, was jeder Origin darf, und die schwache CSP misst.
Prüf, ob es behoben ist
curl -s https://deinedomain.de | grep -oE '<(script|link)[^>]*(src|href)="(https?:)?//[^"]+"[^>]*>' | grep -v integrity
Jede Zeile, die herauskommt, ist eine externe Ressource ohne integrity. Bleiben nur die, die keines vertragen (Schriften, Analyse), bist du fertig.
Häufige Fragen
Verlangsamt SRI das Laden?
Nicht spürbar: Einen SHA-384-Hash einer Datei von ein paar hundert Kilobyte zu berechnen dauert Millisekunden. Was es tut, ist dich zum Fixieren von Versionen zu zwingen, was ohnehin gute Praxis ist.
Muss ich bei einem Bibliotheks-Update den Hash ändern?
Ja, und das ist der Sinn: Das Update geht durch deine Hände. Nutzt du npm und deinen Bundler, ist der Ablauf derselbe wie immer, und der Build kümmert sich um den Hash.
Was ist mit alten Bibliotheksversionen auf dem CDN?
SRI garantiert, dass die Datei die ist, die du gewählt hast, nicht, dass sie sicher ist. Ein jQuery 1.12 mit korrektem Hash hat weiterhin seine Schwachstellen; das erkennt veraltete Bibliotheken.