Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten.Erfahre mehr über dieses Experiment.
Content Security Policy (CSP)
Content Security Policy (CSP) ist ein Feature, das dazu beiträgt, das Risiko bestimmter Arten von Sicherheitsbedrohungen zu verhindern oder zu minimieren. Es besteht aus einer Reihe von Anweisungen einer Website an einen Browser, die den Browser anweisen, Einschränkungen für die Dinge zu setzen, die der Code auf der Seite tun darf.
Der Hauptverwendungszweck von CSP ist die Kontrolle darüber, welche Ressourcen, insbesondere JavaScript-Ressourcen, ein Dokument laden darf. Dies wird hauptsächlich als Schutzmaßnahme gegenCross-Site Scripting (XSS) Angriffe verwendet, bei denen ein Angreifer in der Lage ist, schädlichen Code in die Seite des Opfers einzuschleusen.
Ein CSP kann auch andere Zwecke haben, einschließlich des Schutzes vorClickjacking und der Unterstützung bei der Sicherstellung, dass die Seiten einer Website über HTTPS geladen werden.
In diesem Leitfaden beginnen wir damit, zu beschreiben, wie ein CSP an einen Browser übermittelt wird und wie es auf hoher Ebene aussieht.
Dann beschreiben wir, wie es verwendet werden kann, umzu kontrollieren, welche Ressourcen geladen werden, um sich gegen XSS zu schützen, und dann andere Anwendungsfälle wieClickjacking-Schutz undAufrüsten unsicherer Anfragen. Beachten Sie, dass es keine Abhängigkeit zwischen den verschiedenen Anwendungsfällen gibt: Wenn Sie einen Schutz gegen Clickjacking hinzufügen möchten, aber nicht gegen XSS, können Sie einfach die Anweisungen für diesen Anwendungsfall hinzufügen.
Schließlich beschreiben wirStrategien zur Bereitstellung eines CSP und Werkzeuge, die diesen Prozess einfacher machen können.
In diesem Artikel
CSP-Überblick
Ein CSP sollte dem Browser imContent-Security-Policy-Antwortheader übermittelt werden. Es sollte bei allen Antworten auf alle Anfragen gesetzt werden, nicht nur beim Hauptdokument.
Sie können es auch mit demhttp-equiv-Attribut des<meta>-Elements Ihres Dokuments angeben, und dies ist eine nützliche Option für einige Anwendungsfälle, wie zum Beispiel eine client-seitig gerenderteSingle Page App, die nur statische Ressourcen hat, da Sie dann nicht auf Serverinfrastruktur angewiesen sein müssen. Diese Option unterstützt jedoch nicht alle CSP-Funktionen.
Die Richtlinie wird als eine Reihe vonAnweisungen angegeben, die durch Semikolons getrennt sind. Jede Anweisung steuert einen anderen Aspekt der Sicherheitsrichtlinie. Jede Anweisung hat einen Namen, gefolgt von einem Leerzeichen, gefolgt von einem Wert. Verschiedene Anweisungen können verschiedene Syntaxen haben.
Betrachten Sie zum Beispiel das folgende CSP:
Content-Security-Policy: default-src 'self'; img-src 'self' example.comEs setzt zwei Anweisungen:
- Die
default-src-Anweisung ist auf'self'gesetzt - Die
img-src-Anweisung ist auf'self' example.comgesetzt.
Die erste Anweisung,default-src, weist den Browser an, nur Ressourcen zu laden, die mit dem Dokument gleich-origin sind, es sei denn, andere spezifischere Anweisungen setzen eine andere Richtlinie für andere Ressourcentypen. Die zweite,img-src, weist den Browser an, Bilder zu laden, die gleich-origin sind oder vonexample.com bereitgestellt werden.
Im nächsten Abschnitt werden wir die zur Verfügung stehenden Werkzeuge untersuchen, um das Laden von Ressourcen zu kontrollieren, das die Hauptfunktion eines CSP ist.
Kontrolle des Ladens von Ressourcen
Ein CSP kann verwendet werden, um zu kontrollieren, welche Ressourcen ein Dokument laden darf. Dies wird hauptsächlich zum Schutz gegen Cross-Site Scripting (XSS) Angriffe eingesetzt.
In diesem Abschnitt werden wir zuerst sehen, wie das Kontrollieren des Ressourcenladens helfen kann, sich gegen XSS zu schützen, dann die Werkzeuge, die CSP bietet, um zu kontrollieren, welche Ressourcen geladen werden. Schließlich beschreiben wir eine bestimmte empfohlene Strategie, die als "strikte CSP" bezeichnet wird.
XSS und Laden von Ressourcen
Ein Cross-Site Scripting (XSS) Angriff ist einer, bei dem ein Angreifer in der Lage ist, seinen Code im Kontext der Zielwebsite auszuführen. Dieser Code kann dann alles tun, was der eigene Code der Website tun könnte, einschließlich, zum Beispiel:
- Zugriff oder Modifizierung des Inhalts der geladenen Seiten der Website
- Zugriff oder Modifizierung von Inhalten in lokalem Speicher
- HTTP-Anfragen mit den Anmeldeinformationen des Benutzers ausführen, wodurch er sich als der Benutzer ausgeben oder auf sensible Daten zugreifen kann
Ein XSS Angriff ist möglich, wenn eine Website einige Eingaben akzeptiert, die vom Angreifer erstellt worden sein könnten (zum Beispiel URL-Parameter oder ein Kommentar zu einem Blog-Beitrag) und diese dann in die Seite einfügt, ohne siezu bereinigen: das heißt, ohne sicherzustellen, dass sie nicht als JavaScript ausgeführt werden können.
Websites sollten sich gegen XSS schützen, indem sie diese Eingaben bereinigen, bevor sie in die Seite aufgenommen werden. Ein CSP bietet einen ergänzenden Schutz, der die Website schützen kann, selbst wenn die Bereinigung fehlschlägt.
Wenn die Bereinigung fehlschlägt, gibt es verschiedene Arten, wie der eingeschleuste bösartige Code im Dokument aussehen kann, einschließlich:
Ein
<script>Tag, das auf eine bösartige Quelle verweist:html<script src="https://evil.example.com/hacker.js"></script>Ein
<script>Tag, das Inline-JavaScript enthält:html<script> console.log("You've been hacked!");</script>Ein Inline-Ereignishandler:
html<img onmouseover="console.log(`You've been hacked!`)" src="thumbnail.jpg" alt="" />Eine
#"#"></iframe>
Ein Zeichenfolgenargument für eine unsichere API wieeval():
eval("console.log(`You've been hacked!`)");Ein CSP kann Schutz gegen all diese bieten. Mit einem CSP können Sie:
- die erlaubten Quellen für JavaScript-Dateien und andere Ressourcen definieren und effektiv das Laden von
https://evil.example.comblockieren - Inline-Skripttags deaktivieren
- nur Skripttags zulassen, die das korrekte
nonceoderhashgesetzt haben - Inline-Ereignishandler deaktivieren
#"fetch-richtlinien" >Fetch-Richtlinien
Fetch-Richtlinien werden verwendet, um eine bestimmte Kategorie von Ressourcen anzugeben, die ein Dokument laden darf — wie JavaScript, CSS-Stile, Bilder, Schriftarten und so weiter.
Es gibt verschiedene Fetch-Richtlinien für verschiedene Arten von Ressourcen. Zum Beispiel:
script-srcsetzt erlaubte Quellen für JavaScript.style-srcsetzt erlaubte Quellen für CSS-Stile.img-srcsetzt erlaubte Quellen für Bilder.
Eine spezielle Fetch-Richtlinie ist
default-src, die eine Fallback-Richtlinie für alle Ressourcen setzt, deren Richtlinien nicht explizit aufgelistet sind.Für das komplette Set von Fetch-Richtlinien siehe dieReferenzdokumentation.
Jede Fetch-Richtlinie wird entweder als einzelnes Schlüsselwort
'none'oder ein oder mehrereQuellausdrücke angegeben, die durch Leerzeichen getrennt sind. Wenn mehr als ein Quellausdruck aufgeführt ist: Wenn eine der Methoden die Ressource erlaubt, dann ist die Ressource erlaubt.Zum Beispiel setzt das folgende CSP zwei Fetch-Richtlinien:
default-srcwird der einzelne Quellausdruck'self'gegebenimg-srcerhält zwei Quellausdrücke:'self'undexample.com
Die Wirkung davon ist, dass:
- Bilder entweder gleich-origin mit dem Dokument, oder von
example.comgeladen werden müssen - alle anderen Ressourcen gleich-origin mit dem Dokument sein müssen.
In den nächsten Abschnitten beschreiben wir einige der Möglichkeiten, wie Sie Quellausdrücke verwenden können, um das Laden von Ressourcen zu kontrollieren. Beachten Sie, dass obwohl wir sie separat beschreiben, diese Ausdrücke im Allgemeinen kombiniert werden können: Zum Beispiel kann eine einzelne Fetch-Richtlinie Nonce sowie Hostnamen umfassen.
Blockieren von Ressourcen
Um einen Ressourcentyp vollständig zu blockieren, verwenden Sie das Schlüsselwort
'none'. Zum Beispiel blockiert die folgende Anweisung alle<object>und<embed>Ressourcen:httpContent-Security-Policy: object-src 'none'Beachten Sie, dass
'none'nicht mit einer anderen Methode in einer bestimmten Richtlinie kombiniert werden kann: in der Praxis, wenn andere Quellausdrücke neben'none'angegeben werden, werden sie ignoriert.Nonces
Ein
nonceist der empfohlene Ansatz zur Einschränkung des Ladens von<script>und<style>Ressourcen.Mit einem Nonce erzeugt der Server einen zufälligen Wert für jede HTTP-Antwort und fügt sie in eine
script-src- und/oder einestyle-src-Richtlinie ein:httpContent-Security-Policy: script-src 'nonce-416d1177-4d12-4e3b-b7c9-f6c409789fb8'Der Server fügt dann diesen Wert als Wert des
nonce-Attributs für alle<script>- und/oder<style>-Tags hinzu, die sie im Dokument einfügen möchten.Der Browser vergleicht die beiden Werte und lädt die Ressource nur, wenn sie übereinstimmen. Die Idee ist, dass selbst wenn ein Angreifer etwas JavaScript in die Seite einfügen kann, er nicht wissen wird, welcher Nonce der Server verwenden wird, sodass der Browser sich weigert, das Skript auszuführen.
Damit dieser Ansatz funktioniert, darf es einem Angreifer nicht möglich sein, den Nonce zu erraten.
In der Praxis bedeutet dies, dass der Nonce für jede HTTP-Antwort unterschiedlich sein muss und nicht vorhersehbar sein darf.
Das bedeutet wiederum, dass der Server kein statisches HTML bereitstellen kann, da er bei jeder Anfrage einen neuen Nonce einfügen muss. Typischerweise würde der Server eine Templating-Engine verwenden, um den Nonce einzufügen.
Hier ein Beispielcode vonExpress, um dies zu veranschaulichen:
jsfunction content(nonce) { return ` <script nonce="${nonce}" src="/main.js"></script> <script nonce="${nonce}">console.log("hello!");</script> <h1>Hello world</h1> `;}app.get("/", (req, res) => { const nonce = crypto.randomUUID(); res.setHeader("Content-Security-Policy", `script-src 'nonce-${nonce}'`); res.send(content(nonce));});Bei jeder Anfrage erzeugt der Server einen neuen Nonce, fügt ihn in die CSP und in die
<script>-Tags in dem zurückgesandten Dokument ein. Beachten Sie, dass der Server:- für jede Anfrage einen neuen Nonce erzeugt
- Nonces mit sowohl externen als auch Inline-Skripten verwenden kann
- den gleichen Nonce für alle
<script>-Tags im Dokument verwendet
Es ist wichtig, dass der Server irgendeine Art von Templating verwendet, um Nonces einzufügen, und sie nicht einfach in alle
<script>-Tags einfügt: andernfalls könnte der Server versehentlich Nonces in Skripte einfügen, die von einem Angreifer eingeschleust wurden.Beachten Sie, dass Nonces nur für Elemente verwendet werden können, die ein
nonce-Attribut haben: das heißt, nur<script>und<style>Elemente.Hashes
Fetch-Richtlinien können auch einen Hash des Skripts verwenden, um seine Integrität zu gewährleisten. Mit dieser Methode:
- Berechnet der Server einen Hash des Skriptinhalts mit einerHash-Funktion (einer von SHA-256, SHA-384 oder SHA-512)
- Erstellt eineBase64-Codierung des Ergebnisses
- Fügt ein Präfix hinzu, das den verwendeten Hash-Algorithmus identifiziert (eines von
sha256-,sha384-odersha512-).
Es fügt dann das Ergebnis in die Richtlinie ein:
httpContent-Security-Policy: script-src 'sha256-cd9827ad...'Wenn der Browser das Dokument empfängt, hasht es das Skript, vergleicht das Ergebnis mit dem Wert aus dem Header und lädt das Skript nur, wenn sie übereinstimmen.
Externe Skripte müssen auch das
integrity-Attribut enthalten, damit diese Methode funktioniert.Hier ein Beispielcode von Express, um das zu veranschaulichen:
jsconst hash1 = "sha256-ex2O7MWOzfczthhKm6azheryNVoERSFrPrdvxRtP8DI=";const hash2 = "sha256-H/eahVJiG1zBXPQyXX0V6oaxkfiBdmanvfG9eZWSuEc=";const csp = `script-src '${hash1}' '${hash2}'`;const content = ` <script src="./main.js" integrity="${hash2}"></script> <script>console.log("hello!");</script> <h1>Hello world</h1> `;app.get("/", (req, res) => { res.setHeader("Content-Security-Policy", csp); res.send(content);});Beachten Sie, dass:
- Wir haben einen separaten Hash für jedes Skript im Dokument.
- Für das externe Skript "main.js" fügen wir auch das
integrityAttribut hinzu und geben ihm den gleichen Wert. - Im Gegensatz zum Beispiel zur Verwendung von Nonces können sowohl das CSP als auch der Inhalt statisch sein, da die Hashes gleich bleiben. Dies macht hash-basierte Richtlinien geeigneter für statische Seiten oder Websites, die auf clientseitiges Rendering setzen.
Schema-basierte Richtlinien
Fetch-Richtlinien können ein Schema, wie
https:, auflisten, um Ressourcen zu erlauben, die über dieses Schema bereitgestellt werden. Dies ermöglicht es beispielsweise, das Laden von Ressourcen auf HTTPS zu beschränken:httpContent-Security-Policy: default-src https:Ortsbasierte Richtlinien
Fetch-Richtlinien können Ressourcenladungen basierend darauf steuern, wo sich die Ressourcen befinden.
Das Schlüsselwort
'self'erlaubt Ressourcen, die mit dem Dokument selbst gleich-origin sind:httpContent-Security-Policy: img-src 'self'Sie können auch einen oder mehrere Hostnamen angeben, möglicherweise einschließlich Platzhaltern, und nur von diesen Hosts bereitgestellte Ressourcen werden erlaubt. Dies könnte verwendet werden, um Inhalte von einem vertrauenswürdigen CDN bereitzustellen.
httpContent-Security-Policy: img-src *.example.orgSie können mehrere Standorte angeben. Die folgende Richtlinie erlaubt nur Bilder, die gleich-origin mit dem aktuellen Dokument sind oder von einem Subdomain von "example.org" oder von "example.com" bereitgestellt werden:
httpContent-Security-Policy: img-src 'self' *.example.org example.comInline-JavaScript
Wenn ein CSP entweder eine
default-src- oder einescript-src-Richtlinie enthält, wird das Ausführen von Inline-JavaScript nicht erlaubt, es sei denn, es werden zusätzliche Maßnahmen ergriffen. Dazu gehört:JavaScript, das in einem
<script>-Element auf der Seite enthalten ist:html<script> console.log("Hello from an inline script");</script>JavaScript in einer Inline-Ereignishandlereigenschaft:
html<img src="x" onerror="console.log('Hello from an inline event handler')" />JavaScript in einer
#"#">Click me</a>