FlowingDev

SRI erklärt: Der digitale Fingerabdruck für die Assets deiner Website

Erfahre, wie Subresource Integrity (SRI) kryptografische Hashes verwendet, um deine Seite vor bösartigen Skripten und Stylesheets zu schützen, die von Drittanbieter-CDNs ausgeliefert werden.

Tool ausprobieren: SRI-Hash-Generator

In einem Satz

Subresource Integrity (SRI) ist ein Sicherheitsfeature, mit dem Browser überprüfen können, ob die Dateien, die sie von externen Quellen wie CDNs laden, nicht heimlich manipuliert wurden.

Welches Problem es löst

Stell dir vor: Du baust eine schicke neue Web-App. Um sie richtig flott zu machen, nutzt du ein Content Delivery Network (CDN), um gängige Bibliotheken wie React, Vue oder auch nur ein paar ausgefallene Fonts auszuliefern. Das ist gängige Praxis. Deine Nutzer profitieren von einer schnelleren Erfahrung, weil die Datei wahrscheinlich schon im Cache ihres Browsers liegt, da sie eine andere Seite besucht haben, oder weil sie von einem Server ausgeliefert wird, der physisch näher bei ihnen ist. Win-win, oder?

Meistens. Aber du hast gerade ein massives Vertrauenselement ins Spiel gebracht. Du vertraust darauf, dass der CDN-Anbieter immer die exakte Datei ausliefert, die du beabsichtigt hast. Was aber, wenn dieses CDN gehackt wird? Ein Angreifer könnte die freundliche, hilfreiche react.min.js durch eine bösartige Version ersetzen: react.min.js-plus-ein-crypto-miner-und-passwort-stealer.

Plötzlich läuft dieser bösartige Code auf deiner Website, mit dem vollen Vertrauen der Browser deiner Nutzer. Er kann Login-Daten abgreifen, deine Seiten verunstalten oder deine Besucher in ein Botnet aufnehmen. Das ist eine klassische Supply-Chain-Attacke, und sie ist furchteinflößend, weil du auf deinem eigenen Server nichts falsch gemacht hast. Du hast nur zur falschen Zeit der falschen Partei vertraut.

Vor SRI gab es keinen nativen Browser-Mechanismus, um sich dagegen zu wehren. Entwickler nutzten Notlösungen, aber die waren umständlich. SRI wurde vom W3C geschaffen, um genau dieses Problem direkt anzugehen. Es bietet eine einfache, standardisierte Methode, um dem Browser zu sagen: „Hey, hol dieses Skript, aber bevor du es ausführst, stell absolut sicher, dass es das ist, was ich erwarte. Wenn es auch nur ein Byte abweicht, schmeiß es raus und sag mir Bescheid.“

Wie es unter der Haube funktioniert

SRI ist eine clevere Kombination aus einem einfachen HTML-Attribut und knallharten kryptografischen Prinzipien. Lass es uns aufschlüsseln.

Das integrity-Attribut

Die Magie beginnt mit einem neuen Attribut, das du zu deinen <script>- und <link>-Tags hinzufügen kannst. Es heißt, passenderweise, integrity.

<script
  src="https://code.jquery.com/jquery-3.6.0.min.js"
  integrity="sha384-oBqDVmMz9ATKxIep9tiCxS/Z9fNfEXiDAYTujMAeBAsjFuCZSmKbSSUnQlmh/jp3"
  crossorigin="anonymous"></script>

Dieses Attribut enthält einen String mit zwei Teilen: einem Präfix für den Hash-Algorithmus (hier sha384-) und einem Base64-kodierten kryptografischen Hash. Das ist der „digitale Fingerabdruck“ der Datei, die du zu erhalten erwartest.

Der Hash: Ein digitaler Fingerabdruck

Eine kryptografische Hash-Funktion ist ein mathematischer Algorithmus, der eine Eingabe (wie den gesamten Inhalt einer JavaScript-Datei) entgegennimmt und einen kurzen String mit fester Länge erzeugt, der Hash genannt wird. Stell es dir wie eine Art Super-Prüfsumme vor.

Diese Hashes haben ein paar entscheidende Eigenschaften:

  • Deterministisch: Dieselbe Eingabedatei erzeugt immer exakt denselben Hash.
  • Lawineneffekt: Ändere nur ein einziges Zeichen in der Eingabedatei – füge ein Leerzeichen hinzu, ändere einen Variablennamen – und der resultierende Hash wird komplett anders und nicht wiederzuerkennen sein.
  • Einweg-Funktion: Es ist praktisch unmöglich, den Prozess umzukehren. Du kannst nicht den Hash nehmen und herausfinden, was der ursprüngliche Inhalt der Datei war.

Der SRI-Standard unterstützt drei sichere Hash-Algorithmen: SHA-256, SHA-384 und SHA-512. Die Zahl bezieht sich auf die Bit-Länge des Hashes, und größer ist im Allgemeinen stärker. SHA-384 ist eine super Allround-Wahl.

Wenn du also im Begriff bist, auf eine CDN-Datei zu verlinken, generierst du zuerst deren Hash. Du machst im Wesentlichen einen Schnappschuss der Datei in diesem Moment und sagst dem Browser: „So sieht die echte jquery-3.6.0.min.js aus.“

Das crossorigin-Attribut

Siehst du das crossorigin="anonymous" im Beispiel? Das ist nicht nur zur Deko da; es ist zwingend erforderlich. Damit ein Browser eine Ressource von einem anderen Ursprung (z. B. deine Seite meine-app.de holt ein Skript von code.jquery.com) abrufen und deren Inhalt für die SRI-Prüfung inspizieren kann, benötigt er die Erlaubnis über Cross-Origin Resource Sharing (CORS).

crossorigin="anonymous" weist den Browser an, die Anfrage ohne das Senden von Nutzer-Anmeldeinformationen wie Cookies oder HTTP-Authentifizierungs-Headern zu stellen. Das ist ein Muss für Sicherheit und Datenschutz. Wenn du dieses Attribut vergisst, wird der Browser die Integritätsprüfung verweigern und das Laden der Ressource einfach blockieren, was zu einer kaputten Seite führt.

Alles zusammengefügt: Die Checkliste des Browsers

Wenn ein Browser auf ein Tag mit einem integrity-Attribut stößt, folgt er diesem strengen Protokoll:

  1. Er sieht das <script>-Tag und merkt sich die Attribute src, integrity und crossorigin.
  2. Er sendet eine Anfrage für die Datei unter der src-URL. Dank crossorigin ist dies ein CORS-Request.
  3. Die Datei wird heruntergeladen.
  4. Entscheidend ist: Bevor er irgendetwas ausführt, berechnet der Browser seinen eigenen Hash des Inhalts der heruntergeladenen Datei, wobei er denselben Algorithmus verwendet, der im integrity-Attribut angegeben ist (z. B. sha384).
  5. Dann vergleicht er seinen frisch berechneten Hash mit dem Hash, den du im Attribut angegeben hast.
  6. Wenn sie übereinstimmen: Hurra! Die Datei ist authentisch. Der Browser führt das Skript aus oder wendet das Stylesheet an.
  7. Wenn sie nicht übereinstimmen: ALARMSTUFE ROT! Der Browser geht davon aus, dass die Datei manipuliert wurde. Er verwirft die Datei vollständig und führt sie nicht aus. Dann wirft er einen Failed to find a valid digest-Fehler in die Entwicklerkonsole. Deine Seite mag kaputt aussehen (z. B. ein fehlendes Diagramm oder eine fehlende Schriftart), aber du bist gerade noch mal mit einem blauen Auge davongekommen.

Geschichten aus der Praxis

Das verunstaltete Analytics-Dashboard

Ein Marketing-Team verließ sich auf ein Dashboard, das eine Charting-Bibliothek eines Drittanbieters verwendete, die von einem Nischen-CDN bezogen wurde, um ihre Kampagnendaten zu visualisieren. Der Entwickler, der sich gerade über Security Best Practices informiert hatte, hatte SRI-Hashes zum <script>-Tag der Bibliothek hinzugefügt. Eines Montagmorgens wurde das CDN kurzzeitig kompromittiert. Ein Angreifer ersetzte die beliebte Charting-Bibliothek durch ein Skript, das nur ein riesiges, spöttisches Gesicht aus ASCII-Art anzeigte.

Als das Marketing-Team sein Dashboard lud, waren die Diagramme kaputt. Sie sahen leere Kästen. Genervt riefen sie die IT an. Der Entwickler überprüfte die Browser-Konsole und sah den wunderschönen, wunderschönen SRI-Validierungsfehler. Der Browser hatte die modifizierte Datei erkannt, ihre Ausführung verweigert und die Verunstaltung verhindert. Anstelle eines großen Sicherheitsvorfalls und einer panischen Geschäftsleitung war es eine 15-minütige Untersuchung, die damit endete, dass vorübergehend auf ein anderes CDN umgestellt wurde.

Lektion: SRI verwandelt eine potenzielle Sicherheitskatastrophe in ein überschaubares Verfügbarkeitsproblem.

Der heimliche Crypto-Miner

Eine beliebte, leichtgewichtige JavaScript-Utility-Bibliothek, die auf einem kostenlosen CDN gehostet wurde, war ein Liebling von Indie-Entwicklern. Ein Angreifer verschaffte sich Zugang zum CDN und modifizierte die Bibliotheksdatei, indem er ein paar verschleierte Code-Zeilen hinzufügte, die einen WebAssembly-Crypto-Miner starteten. Die Dateigröße änderte sich kaum, und die Kernfunktionen der Bibliothek funktionierten immer noch einwandfrei.

Websites, die die Bibliothek ohne SRI verwendeten, brachten plötzlich die Laptops ihrer Nutzer dazu, die Lüfter hochzudrehen und die Akkus leerzusaugen. Nutzer beschwerten sich über Trägheit, aber die Ursache war schwer zu diagnostizieren. Die Websites selbst sahen gut aus. Websites, die jedoch SRI implementiert hatten, waren immun. Ihre Browser blockierten das modifizierte Skript, und obwohl die Utility-Funktionen kaputtgingen, waren die CPUs ihrer Nutzer sicher.

Lektion: SRI fängt nicht nur offensichtliche Verunstaltungen ab, sondern auch subtile, parasitäre Angriffe, die dem Ruf deiner Seite schaden können.

Das vergessene Font-Update

Ein Designer bestand darauf, eine bestimmte Version einer Schriftart von einer Drittanbieter-Schriftgießerei zu verwenden, die über deren CDN ausgeliefert wurde. Der Entwickler kopierte pflichtbewusst das <link>-Tag, komplett mit seinem SRI-Hash. Die Seite ging online und sah großartig aus. Sechs Monate später aktualisierte die Gießerei die Schriftartdatei, um neue Währungssymbole hinzuzufügen und das Kerning zu verbessern. Es war ein legitimes, hilfreiches Update.

Plötzlich fiel der Text der Seite auf hässliches Standard-Arial zurück. Der Entwickler war verblüfft, bis er die Konsole überprüfte und den SRI-Fehler sah. Der Browser blockierte korrekterweise die neue, modifizierte Schriftartdatei, weil ihr Hash nicht mehr mit dem alten im HTML übereinstimmte. Der „Angriff“ war nur ein harmloses Update, aber SRI hat seine Arbeit getan. Die Lösung war einfach: einen neuen Hash für die aktualisierte Schriftart generieren und die Änderung bereitstellen.

Lektion: SRI erzwingt eine strikte Versionierung. Es schützt dich vor bösartigen Änderungen und unerwarteten Upstream-Updates und zwingt dich, bewusst mit den Assets umzugehen, die du verwendest.

Häufige Fehler und Fallstricke

  • crossorigin="anonymous" vergessen. Das ist der Fehler Nummer 1. Ohne dieses Attribut hat der Browser keine CORS-Erlaubnis, die Ressource zu inspizieren, also blockiert er sie aus Sicherheitsgründen einfach. Es findet keine Integritätsprüfung statt. Dein Skript oder dein Stylesheet wird einfach nicht geladen.
  • Das Falsche hashen. Du musst den exakten Inhalt der Datei hashen, den der Browser empfängt. Hashe keine lokale, unkomprimierte Version eines Skripts, wenn du auf die minifizierte CDN-Version verlinkst. Hashe nicht den URL-String selbst. Du brauchst den Hash des Datei-Inhalts (Body).
  • Schwache Hash-Algorithmen verwenden. MD5 und SHA-1 haben bekannte Schwachstellen und sollten nicht für Sicherheitszwecke verwendet werden. Die Spezifikation verlangt, dass Browser mindestens SHA-256, SHA-384 und SHA-512 unterstützen. Halte dich an diese.
  • Den Hash nach einem legitimen Update nicht aktualisieren. SRI ist ein Feature, kein Bug. Wenn die Datei, auf die du verlinkst, aus irgendeinem Grund aktualisiert wird, musst du einen neuen Integritäts-Hash generieren und dein HTML-integrity-Attribut aktualisieren. Wenn du das nicht tust, wird die Ressource blockiert.
  • Denken, es schützt den eigenen Server. SRI ist dafür konzipiert, Ressourcen von Drittanbietern zu validieren. Wenn ein Angreifer deinen Server so weit kompromittiert hat, dass er deine HTML-Dateien ändern kann, kann er einfach den SRI-Hash so ändern, dass er zu seinem bösartigen Skript passt. Für Same-Origin-Ressourcen bietet es keinen Vorteil.

Warum du das auf dem Schirm haben solltest

Du solltest jedes einzelne Mal über SRI nachdenken, wenn du ein <script src="..."> oder <link rel="stylesheet" href="..."> schreibst, das auf eine Domain verweist, die du nicht kontrollierst.

Es ist ein fundamentaler Baustein moderner Web-Sicherheit. In einer Welt, die auf NPM, CDNs und einem komplexen Netz von Abhängigkeiten von Drittanbietern aufbaut, ist deine Supply-Chain eine riesige Angriffsfläche. SRI ist eines der einfachsten und effektivsten Werkzeuge, um diese Fläche zu härten. Es ist deine erste Verteidigungslinie gegen ein kompromittiertes CDN. Gepaart mit einer Content Security Policy (CSP) bietet es einen robusten, mehrschichtigen Schutz.

Das Hinzufügen von SRI dauert ein paar Sekunden, wenn du eine Ressource einbindest, aber es kann dir später eine Menge Ärger ersparen. Es verwandelt einen leisen, gefährlichen Exploit in einen lauten, sicheren Fehlschlag.

Tauch tiefer ein

Theorie erledigt. Zeit, loszulegen — 100 % in deinem Browser.

Tool ausprobieren: SRI-Hash-Generator