Die Subresource Integrity (SRI) ist ein wichtiger Bestandteil zur Sicherheit von Webseiten
Die Subresource Integrity (SRI) ist ein Sicherheitsverfahren, das davor schützt, nachträglich veränderte Scripte oder CSS-Dateien in Webseiten zu laden.Dabei wird auf Hash-Werte zurückgegriffen die eine geladene Datei eindeutig identifizierbar macht.
D. h.: entspricht der angegebene Hash nicht dem der externen Datei, wird diese nicht geladen.
Man erhält dadurch immer genau die Version der Datei, die man aufgrund des Hashes erwartet.
Angenommen, die externe Ressource wurde geändert | ||
3. User Agent verweigert die Datei | 1. Anforderung einer Ressource mit SRI-Hash > | Server mit kompromittierten Dateien. |
< 2. Server liefert Datei mit falschem Hash. |
Überprüfung der SRI einer Webseite
Das einfachste Mittel zum Überprüfen der SRI einer Seite ist die Webseite Dort können Sie eine URL eingeben und sehen, ob alle externen Scripte oder CSS-Dateien mit SRI geladen wurden.

Implementierung auf der Webseite
- integrity
- Hier folgt nach der Angabe des Hash-Algorithmus (als Präfix), getrennt durch einen „-“, der base64 kodierte Hash.
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
Es können hier mehrere Hashes angeben werden. Diese werden durch ein Leerzeichen getrennt.
In diesem Fall wählt der User-Agent die stärkste Hash-Funktion aus, um die Datei zu überprüfen.<script src="/hello_world.js" integrity="sha384-H8BRh8j48O9oYatfu5AZzq6A9RINhZO5H16dQZngK7T62em8MUt1FLm52t+eX6xO sha512-Q2bFTOhEALkN8hOms2FKTDLy7eugP2zFZ1T8LCvX42Fp3WoNr3bjZSAHeOsHrbV1Fu9/A0EzCinRE7Af1ofPrw==" crossorigin="anonymous"> </script>
Konforme User-Agents müssen die Hash-Funktionen sha256, sha384 und sha512 unterstützen. - crossorigin
-
crossorigin="anonymous"
Wenn die Anfrage nicht den gleichen Ursprung hat, muss hieranonymous
angegeben werden. Ist dies nicht der Fall, behandelt der Browser die Datei, als ob das Integritätsattribut nicht gesetzt ist. Dadurch geht die Sicherheit durch SRI wieder verloren.
Erstellen einer SRI
Online
Die Hashes können z. B. auf der Seite SRI Hash Generator erzeugt werden.Offline / Direkt
Verschiedene Methoden zum Erzeugen des Hashes
cat FILENAME.js | openssl dgst -sha384 -binary | openssl base64 -A
shasum -b -a 384 FILENAME.js | awk '{ print $1 }' | xxd -r -p | base64
<?php
function checksum($input) {
$hash = hash('sha256', $input, true);
$hash_base64 = base64_encode($hash);
return "sha256-$hash_base64"; }
?>
CDN Anbieter
CDNs wie z. B. jsDelivr bieten die Möglichkeit, die SRI automatisch zu erzeugen:
Automatische Erzeugung
Eine leider oft gezeigte Methode, die Hashes, z. B. über PHP, automatisch zu erzeugen ist folgende:
<?php
$data = file_get_contents("https://code.jquery.com/jquery-3.6.0.min.js");
echo base64_encode(hash("sha256", $data, true));
>
Mit dieser Methode wird der Sicherheitsmechanismus der SRI ausgehebelt. Damit lässt sich nicht mehr feststellen, ob die Ressource kompromittiert ist, da der User-Agent keinen Vergleich hat, sondern nur den Hash der externen Datei und dieser wird immer stimmen.
Der Hash muss bei so einer Vorgehensweise nicht von der externen, sondern von einer sicheren lokalen Ressource erzeugt werden.Rein aus Performancegründen sollte dies nicht bei jedem Seitenaufruf geschehen, sondern, nur wenn sich die Dateien geändert haben.
Fallback
Sollte das Laden der externen Ressource fehlschlagen, ist es sinnvoll, auf eine lokale Kopie zurückzugreifen.
<script>
window.jQuery ||
document.write(
'<script window.jQuery || document.write('<script src="/js/jquery.min.js"><\/script>');
</script>
Im Zusammenhang mit einer Content-Security-Policy (CSP) sollte das vorherige Beispiel nicht lauffähig sein, da hier ein Inline-Script erzeugt wird. Ein
unsafe-inline
, in der CSP, sollte bei Scripten vermieden werden.Deshalb fügt man hier eine passende
nonce
ein:
<script nonce="anF1ZXJ5ZmsbGJhY2s=">
window.jQuery ||
document.write(
'<script window.jQuery || document.write('<script src="/js/jquery.min.js"><\/script>');
</script>
und passt die CSPs entsprechend an:
default-src 'none';
script-src 'nonce-anF1ZXJ5ZmsbGJhY2s=';
connect-src 'self';
img-src 'self';
style-src 'self';
base-uri 'self';
form-action 'self';
Alternativ kann man auch ein Script wie Subresource Integrity Fallback verwendet. Dieses lädt im Fehlerfall die lokale Ressource.
Das Script muss vor allen anderen Ressourcen geladen werden.
<script
src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
data-sri-fallback="/js/jquery.min.js"
crossorigin="anonymous">
</script>
Mit dem Data-Attribute data-sri-fallback
wird hier die lokale Datei angegeben. Dieses Script muss lokal vorhanden sein, sonst funktioniert bei einem CDN-Fehler auch dieses nicht.
Weitere Beispiele
Für CSS-Dateien:
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x"
crossorigin="anonymous">
Test einer SRI
Wenn Sie eine SRI das erste Mal auf Ihrer Seite einsetzen, sollten Sie anschließend folgendes überprüfen:- Gibt es Fehlermeldungen in der Browser-Konsole?
- Sind noch alle Funktionen der Seite gegeben?
Fehlermeldung in der Browser-Konsole


Zusammenfassung
SRI über HTTP bringt wenig Nutzen, da die Übertagung beeinflusst werden kann. SRI ist nur im Zusammenspiel mit HTTPS sinnvoll.
SRI kann, was CSP und HTTPS nicht können: Überprüfen, ob auch der richtige Inhalt geladen wird.
Checkliste
- Jede externe Ressource (CSS oder Script) hat ein passendes
integrity
Attribut. crossorigin="anonymous"
, sonst wird der Hash nicht überprüft.- Der Hash muss von einer bekannten, sicheren Quelle stammen.
- Bei einer Änderung der externen Ressource / Quelle muss der Hash neu erzeugt werden!
Tools
Weiterführende Informationen
- Content-Security-Policy (CSP)
- W3C: Subresource Integrity
- MDN: Subresource Integrity
- Wikipedia: Subresource Integrity
- Hashfunktion
- SHA-2
- Can I use: Subresource Integrity