Heim >Web-Frontend >H5-Tutorial >Einführung in die HTML5-Sicherheit: Einführung in die Content Security Policy (CSP)_html5-Tutorialfähigkeiten
Die Sicherheitsrichtlinie des World Wide Web basiert auf der Same-Origin-Richtlinie. Beispielsweise kann der Code von www.jb51.net nur auf die Daten von www.jb51.net zugreifen, hat jedoch keine Berechtigung für den Zugriff auf http://www.baidu.com. Jeder Ursprung ist vom Rest des Netzwerks isoliert, wodurch eine sichere Sandbox für Entwickler entsteht. Theoretisch ist das perfekt, doch nun haben Angreifer clevere Wege gefunden, dieses System zu kompromittieren.
Hierbei handelt es sich um einen XSS-Cross-Site-Scripting-Angriff, der die Same-Origin-Richtlinie durch falsche Inhalte und Täuschungsklicks umgeht. Dies ist ein großes Problem, und wenn ein Angreifer erfolgreich Code einschleust, kann eine beträchtliche Menge an Benutzerdaten verloren gehen.
Jetzt führen wir eine neue und wirksame Sicherheitsverteidigungsstrategie ein, um dieses Risiko zu mindern: die Content Security Policy (CSP).
Source Whitelist
Der Kern des XSS-Angriffs besteht darin, dass der Browser nicht unterscheiden kann, ob das Skript von einem Dritten eingeschleust wurde oder wirklich Teil Ihrer Anwendung ist. Beispielsweise lädt die Schaltfläche „Google 1“ Code von https://apis.google.com/js/plusone.js und führt ihn aus. Wir können jedoch nicht erwarten, anhand des Bildes im Browser festzustellen, dass der Code tatsächlich von apis.google stammt .com , wiederum von apis.evil.example.com. Der Browser lädt beliebigen Code bei Seitenanfragen herunter und führt ihn aus, unabhängig von seiner Herkunft.
CSP definiert den Content-Security-Policy-HTTP-Header, um Ihnen die Erstellung einer Whitelist vertrauenswürdiger Quellen zu ermöglichen, sodass der Browser nur Ressourcen aus diesen Quellen ausführt und rendert, anstatt blind allen vom Server bereitgestellten Inhalten zu vertrauen. Selbst wenn ein Angreifer eine Schwachstelle zum Einschleusen eines Skripts findet, wird dieses nicht ausgeführt, da die Quelle nicht in der Whitelist enthalten ist.
Am Beispiel der Google 1-Schaltfläche oben können wir, da wir der Meinung sind, dass apis.google.com und wir selbst gültigen Code bereitstellen, eine Richtlinie definieren, die es dem Browser erlaubt, nur Skripte von einem der beiden folgenden auszuführen Quellen.
Content-Security-Policy:script-src 'self' https://apis.google.com
Ist das nicht ganz einfach? script-src kann skriptbezogene Berechtigungen für die angegebene Seite steuern. Auf diese Weise lädt der Browser nur Skripts von http://apis.google.com und dieser Seite selbst herunter und führt sie aus.
Sobald wir diese Strategie definiert haben, gibt der Browser einen Fehler aus, wenn er den eingefügten Code erkennt (beachten Sie, um welchen Browser es sich handelt).
Die Inhaltssicherheitsrichtlinie gilt für alle häufig verwendeten Ressourcen.
Obwohl Skriptressourcen das offensichtlichste Sicherheitsrisiko darstellen, bietet CSP auch einen umfangreichen Satz von Anweisungen, mit denen die Seite das Laden verschiedener Arten von Ressourcen steuern kann, z Folgende Typen:
content-src: Beschränken Sie den Verbindungstyp (z. B. XHR, WebSockets und EventSource)
font-src: Steuern Sie die Quelle von Webschriftarten. Beispielsweise können die Webfonts von Google über den Font-src https://themes.googleusercontent.com genutzt werden.
frame-src: Listet die Quellen von Frames auf, die eingebettet werden können. Frame-src https://youtube.com erlaubt beispielsweise nur das Einbetten von YouTube-Videos. .
img-src: Definiert die Quelle ladbarer Bilder.
media-src: Video- und Audioquellen einschränken.
object-src: Beschränken Sie die Quelle von Flash und anderen Plug-Ins.
style-src: ähnelt Script-src, gilt jedoch nur für CSS-Dateien.
Standardmäßig sind alle Einstellungen ohne Einschränkungen aktiviert. Sie können mehrere Direktiven durch Semikolons trennen, aber in der Form script-src https://host1.com;script-src https://host2.com wird die zweite Direktive ignoriert. Der richtige Weg, es zu schreiben, ist script-src https://host1.com https://host2.com.
Wenn Sie beispielsweise eine Anwendung haben, die alle Ressourcen von einem Content Delivery Network (CDN, z. B. https://cdn.example.net) laden muss, und Sie wissen, dass es keinen Inhalt gibt, der nicht benötigt wird Alle Frames oder Plug-Ins, Ihre Strategie könnte wie folgt aussehen:
Content-Security-Policy:default-src https://cdn.example.net;
Details
Ich verwende im Beispiel Der HTTP-Header ist Content-Security-Policy, aber moderne Browser bieten bereits Unterstützung über Präfixe: Firefox verwendet x-Content-Security-Policy, WebKit verwendet X-WebKit-CSP. Zukünftig wird es einen schrittweisen Übergang zu einheitlichen Standards geben.
Strategien können für jede einzelne Seite festgelegt werden, was große Flexibilität bietet. Denn einige Seiten Ihrer Website verfügen möglicherweise über Google 1-Schaltflächen, andere jedoch möglicherweise nicht.
Die Quellliste für jede Direktive kann sehr flexibel sein. Sie können das Muster (data:, https:) oder den Hostnamen in einem Bereich (example.com) angeben, der jedem Ursprung, jedem Muster und jedem Port entspricht auf dem Host) oder geben Sie einen vollständigen URI an (https://example.com:443, insbesondere https-Protokoll, example.com-Domänenname, Port 443).
Es gibt vier weitere Schlüsselwörter, die Sie in Ihrer Quellenliste verwenden können:
„none“: Sie erwarten möglicherweise keine Übereinstimmung.
„self“: dasselbe wie die aktuelle Quelle, jedoch ohne Subdomains.
„unsafe-inline ": ermöglicht Inline-Javascript und CSS
"unsafe-eval": ermöglicht Text-zu-JS-Mechanismen wie eval
Bitte beachten Sie, dass diese Schlüsselwörter in Anführungszeichen gesetzt werden müssen.
Sandbox
Hier gibt es noch eine weitere Richtlinie, die es wert ist, diskutiert zu werden: Sandbox. Es ist etwas inkonsistent mit anderen Anweisungen. Es steuert hauptsächlich die auf der Seite durchgeführten Aktionen und nicht die Ressourcen, die die Seite laden kann. Wenn dieses Attribut festgelegt ist, verhält sich die Seite wie ein Frame mit festgelegtem Sandbox-Attribut. Dies hat vielfältige Auswirkungen auf die Seite, z. B. das Verhindern von Formularübermittlungen usw. Dies würde den Rahmen dieses Artikels etwas sprengen, aber weitere Informationen finden Sie im Kapitel „Sandbox-Flag-Einstellungen“ der HTML5-Spezifikation.
Schädlicher Inline-Code
CSP basiert auf Source-Whitelisting, kann aber die größte Quelle von XSS-Angriffen nicht lösen: Inline-Script-Injection. Wenn ein Angreifer ein Skript-Tag (
) einschleusen kann, das schädlichen Code enthält, verfügt der Browser nicht über einen guten Mechanismus, um dieses Tag zu unterscheiden. CSP kann dieses Problem nur lösen, indem es Inline-Skripte vollständig deaktiviert. Dieses Verbot gilt nicht nur für in Skripts eingebettete Skript-Tags, sondern auch für Inline-Ereignishandler und javascrpt:-URLs. Sie müssen den Inhalt des Skript-Tags in eine externe Datei einfügen und javascript: und
durch die entsprechenden addEventListener-Methoden ersetzen. Beispielsweise könnten Sie die folgende Form umschreiben:
Bin ich großartig?
in die folgende Form umschreiben:
Bin ich großartig?
// awesome.js
function doAmazingThings() {
warning('YOU AMAZING!');
}
document. addEventListener('DOMContentReady', function () {
document.getElementById('amazing')
.addEventListener('click', doAmazingThings);
});
Ob CSP verwendet wird oder nicht, The Der obige Code hat tatsächlich größere Vorteile. Inline-JavaScript vermischt vollständig Struktur und Verhalten, und das sollten Sie nicht tun. Darüber hinaus lassen sich externe Ressourcen von Browsern leichter zwischenspeichern, sind für Entwickler leichter zu verstehen und einfacher zu kompilieren und zu komprimieren. Wenn Sie externen Code verwenden, schreiben Sie besseren Code.
Inline-Stile müssen auf die gleiche Weise gehandhabt werden, sowohl Stilattribute als auch Stil-Tags müssen in externe Stylesheets extrahiert werden. Dies verhindert alle möglichen magischen Arten von Datenlecks.
Wenn Sie Inline-Skripte und -Stile benötigen, können Sie den Wert „unsafe-inline“ für das Attribut „script-src“ oder „style-src“ festlegen. Tun Sie dies jedoch nicht. Das Deaktivieren von Inline-Skripten ist die größte Sicherheitsgarantie, die CSP bietet. Das Deaktivieren von Inline-Stilen kann Ihre Anwendung sicherer und robuster machen. Es ist ein Kompromiss, aber es lohnt sich.
Eval
Auch wenn der Angreifer das Skript nicht direkt einschleusen kann, kann er Ihre Anwendung dazu verleiten, den eingefügten Text in ein ausführbares Skript umzuwandeln und sich selbst auszuführen. eval() , newFunction() , setTimeout([string], ...) und setInterval([string], ...) können alle Vektoren dieser Gefahr sein. Die Strategie von CSP für dieses Risiko besteht darin, diese Vektoren vollständig zu blockieren.
Dies hat einige Auswirkungen auf die Art und Weise, wie Sie Ihre Anwendungen erstellen:
Analysieren Sie JSON über die integrierte JSON.parse, anstatt sich auf eval zu verlassen. Browser nach IE8 unterstützen lokale JSON-Vorgänge, was völlig sicher ist.
Schreiben Sie die Art und Weise, wie Sie setTimeout und setInterval aufrufen, neu, indem Sie Inline-Funktionen anstelle von Zeichenfolgen verwenden. Zum Beispiel:
setTimeout("document.querySelector('a').style.display = 'none';", 10);
Kann umgeschrieben werden als:
setTimeout(function () { document. querySelector ('a').style.display = 'none'; }, 10); Vermeiden Sie Inline-Vorlagen zur Laufzeit: Viele Vorlagenbibliotheken verwenden new Function(), um die Vorlagengenerierung zu beschleunigen. Das ist großartig für dynamische Programme, aber riskant für bösartigen Text.
Berichte
Die Fähigkeit von CSP, nicht vertrauenswürdige Ressourcen auf der Serverseite zu blockieren, ist großartig für Benutzer, aber es ist großartig für uns, die verschiedenen Benachrichtigungen an den Server gesendet zu bekommen, damit wir jede schädliche Skripteinschleusung identifizieren und beheben können. Zu diesem Zweck können Sie den Browser über die Direktive „report-uri“ anweisen, einen Abhörbericht im JSON-Format an eine bestimmte Adresse zu senden. <script>sendMyDataToEvilDotCom();</script>Content-Security-Policy: default-src 'self' ...; report-uri /my_amazing_csp_report_parser;<script><br /> function doAmazingThings() {<br /> alert('YOU AM AMAZING!');<br /> }<br /></script>Der Bericht sieht folgendermaßen aus:
{
"csp-report": {
"document-uri": "http://example.org/page.html",
"referrer" : "http://evil.example.com/",
"blocked-uri": "http://evil.example.com/evil.js",
"violated-directive": " script -src 'self' https://apis.google.com",
"original-policy": "script-src 'self' https://apis.google.com; report-uri http:// example .org/my_amazing_csp_report_parser"
}
}
Die darin enthaltenen Informationen helfen Ihnen, die Abhörsituation zu identifizieren, einschließlich der Seite, auf der das Abfangen stattgefunden hat (document-uri), des Referrers der Seite und der Ressourcen, die gegen die Seitenrichtlinie (blocked-uri), die verletzte Richtlinie und alle Inhaltssicherheitsrichtlinien der Seite (original-policy) verstoßen.
Nutzung in der Praxis
CSP ist jetzt in Chrome 16 und Firefox 4 verfügbar und wird voraussichtlich nur begrenzte Unterstützung in IE10 haben. Safari unterstützt es noch nicht, aber nächtliche Builds von WebKit sind verfügbar. Sie können also davon ausgehen, dass Safari es in der nächsten Iteration unterstützen wird.
Schauen wir uns einige häufige Anwendungsfälle an:
Praktischer Fall 1: Social-Media-Widget
Die Google 1-Schaltfläche enthält Skripte von https://apis.google.com und ist von https:// iframe für plusone eingebettet .google.com. Ihre Strategie muss diese Quellen einbeziehen, um die Google 1-Schaltfläche verwenden zu können. Die einfachste Strategie ist script-src https://apis.google.com; frame-src https://plusone.google.com. Sie müssen außerdem sicherstellen, dass die von Google bereitgestellten JS-Snippets in externen JS-Dateien gespeichert werden.
Es gibt viele Implementierungslösungen für den Like-Button von Facebook. Ich empfehle Ihnen, bei der Iframe-Version zu bleiben, da diese gut vom Rest Ihrer Website isoliert bleibt. Dies erfordert die Verwendung der Frame-src https://facebook.com-Direktive. Bitte beachten Sie, dass der von Facebook bereitgestellte Iframe-Code standardmäßig den relativen Pfad //facebook.com verwendet. Bitte ändern Sie diesen Code in https://facebook.com. Sie können HTTP nicht verwenden.
Der Tweet-Button von Twitter basiert auf Skript und Frame, die beide von https://platform.twitter.com stammen (Twitter stellt standardmäßig relative URLs bereit, bitte bearbeiten Sie den Code, um beim Kopieren HTTPS anzugeben).
Andere Plattformen haben ähnliche Situationen und können auf ähnliche Weise gelöst werden. Ich empfehle, „default-src“ auf „none“ zu setzen und dann in der Konsole zu überprüfen, welche Ressourcen Sie benötigen, um sicherzustellen, dass das Widget ordnungsgemäß funktioniert.
Die Verwendung mehrerer Widgets ist sehr einfach: Führen Sie einfach alle Strategieanweisungen zusammen und denken Sie daran, die Einstellungen für dieselbe Anweisung zusammenzuhalten. Wenn Sie die drei oben genannten Widgets verwenden möchten, sieht die Strategie wie folgt aus:
script-src https://apis.google.com https://platform.twitter.com; .google.com https://facebook.com https://platform.twitter.com
Praktischer Fall 2: Verteidigung
Angenommen, Sie besuchen die Website einer Bank und möchten sicherstellen, dass nur die Ressourcen geladen werden, die Sie benötigen. Legen Sie in diesem Fall zunächst eine Standardberechtigung zum Blockieren aller Inhalte fest (default-src „none“) und erstellen Sie die Richtlinie von Grund auf.
Beispielsweise muss eine Bank-Website Bilder, Stile und Skripte aus dem CDN von https://cdn.mybank.net laden und über XHR eine Verbindung zu https://api.mybank.com/ herstellen, um verschiedene Daten abzurufen . Sie müssen auch Frames verwenden, aber Frames stammen von lokalen Seiten, die nicht von Drittanbietern stammen. Auf der Website gibt es kein Flash, keine Schriftarten und keine anderen Inhalte. In diesem Fall ist der strengste CSP-Header, den wir senden können:
Content-Security-Policy: default-src 'none'; .mybank.net; img-src https://cdn.mybank.com; connect-src 'self'
Tatsächlicher Fall 3: Nur SSL verwenden
Ein Administrator eines Ehering-Forums möchte, dass alle Ressourcen auf sichere Weise geladen werden, möchte jedoch nicht zu viel Code schreiben. Das Umschreiben einer großen Anzahl von Inline-Skripten und -Stilen von Drittanbietern übersteigt seine Fähigkeiten. Daher ist die folgende Richtlinie sehr nützlich:
Content-Security-Policy: default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'
Obwohl Standard -src gibt https an, Skripte und Stile werden nicht automatisch vererbt. Jede Anweisung überschreibt den Standardressourcentyp vollständig.
Zukunft
Die W3C-Arbeitsgruppe für Webanwendungssicherheit formuliert die Details der Spezifikation für Inhaltssicherheitsrichtlinien. Version 1.0 steht kurz vor dem Eintritt in die letzte Überarbeitungsphase und kommt dem, was in diesem Artikel beschrieben wird, sehr nahe. Die Mailinggruppe public-webappsec@ diskutiert Version 1.1, und auch Browserhersteller arbeiten hart daran, die Implementierung von CSP zu konsolidieren und zu verbessern.
CSP 1.1 verfügt über einige interessante Funktionen auf der Zeichenfläche, die es wert sind, gesondert aufgeführt zu werden:
Hinzufügen von Richtlinien über Meta-Tags: Die bevorzugte Methode zum Festlegen von CSP sind HTTP-Header, die sehr nützlich sind, aber das Festlegen über Tags oder Skripte ist einfacher , aber vorerst noch nicht abgeschlossen. WebKit hat die Funktion zum Festlegen von Berechtigungen über Metaelemente implementiert, sodass Sie jetzt die folgenden Einstellungen in Chrome ausprobieren können: Fügen Sie
Sie können zur Laufzeit sogar Strategien per Skript hinzufügen.
DOM-API: Wenn die nächste Iteration von CSP diese Funktion hinzufügt, können Sie die aktuelle Sicherheitsrichtlinie der Seite über Javascript abfragen und sie an verschiedene Situationen anpassen. Beispielsweise kann Ihre Code-Implementierung etwas anders sein, wenn eval() verfügbar ist. Dies ist für JS-Framework-Autoren sehr nützlich. Da die API-Spezifikation derzeit sehr unsicher ist, finden Sie die neueste Version im Kapitel „Skriptschnittstelle“ des Spezifikationsentwurfs.
Neue Direktiven: Viele neue Direktiven werden diskutiert, darunter „script-nonce:“ nur explizit angegebene Skriptelemente können Inline-Skripte verwenden: Dadurch wird die Art der Plugins eingeschränkt eine bestimmte Quelle.
Wenn Sie an Diskussionen über diese zukünftigen Funktionen interessiert sind, können Sie die Archive der Mailingliste lesen oder der Mailingliste beitreten.
Dieser Artikel wurde übersetzt von: http://www.html5rocks.com/en/tutorials/security/content-security-policy/
Auszug aus: Jiang Yujies Blog