Content-Security-Policy

Sichere Websites

Dienstag, 1. Oktober 2019

Alle moderne Webbrowser erlauben über die Content-Security-Policy (kurz CSP) einzuschränken aus welcher Quelle Daten (Scripts,  Stylesheets, Fonts, Bilder etc.) nachgeladen werden und ausgeführt werden dürfen.

Warum CSP?

Der User eine Website ist dadurch besser vor Cross-Site-Scripting (XXS) Attacken geschützt. Diese werden verwendet um Nutzerdaten abzugreifen oder Malware und sonstigen bösartigen Code auszuführen.

Aufbau

Die Content-Security-Policy lässt per HTTP Header oder Metatag setzen und hat folgendes Format (in allen modernen Browsern Chrome/Firefox/Safari/Edge/Opera)

Content-Security-Policy: policy

 (Internet Explorer >= 10)

X-Content-Security-Policy: policy 

Beispiel

Content-Security-Policy: default-src 'none' ; scripts-src 'self'; report-uri /report

Die Policy besteht aus mehreren Direktiven die durch ein Semikolon getrennt werden.

Zwischen der Direktive und den jeweils möglichen werte steht KEIN Doppeltpunkt da diese auch in den Werten vorkommen kann. Einzelne Werte sind nur durch Leerzeichen getrennt.

Inzwischen gibt es 3 verschiedene Levels der CSP (Siehe Hinweis in der Tabelle)

Direktive

Direktive Erklärung CSP Level

default-src

Voreinstellung wenn keine weitere Richtline angegeben wurde. Hat man Beispielsweise bei default-src 'self' angegeben aber kein img-src, gilt dort 'self'

1

script-src

Einstellung für alle Javascripts

1

script-src-elem

Einstellung nur für script tag

script-src-attr

Einstellung nur für inline script (onlick='')

style-src

Einstellung für Stylesheets

1

style-src-elem

Einstellung für Style tag

style-src-attr

Einstellung für inline styles (<tag style='''>)

font-src

Quellen für Fonts

1

object-src

Quellen für Plugins in object, embed und applet tags

1

img-src

Quellen für Bilder

worker-src

Quelle für Worker, SharedWorker und ServiceWorker Scripts

3

manifest-src

Quelle für Manifest (Progressive Webapps)

3

connect-src

Quellen für Ajax, WebSocket und EventSources

prefetch-src

Quellen für Vorausladen (prefetched)

media-src

Quellen für Audio/Video

child-src

Quellen für Verschachtelte Ressourcen (d.h. was kann in iframe/frame nachgeladen werden)

form-action

Ziele für form action

frame-ancestors

Seite darf Quelle für frame/iframe dieser Seiten sein.

2

base-uri

Einschränkung für base element

 

plugin-types

Definiert Mime Typen für plugins

sandbox

Gibt an was nachgeladene Ressourcen dürfen  (ähnlich <iframe sandbox)

report-uri

report-to

URL an die eine Violation gesendet wird

 Werte

Wert Beschreibung

*

Alles ist erlaubt mit Ausnahme von data: blob: filesystem: und schemes:

'none'

Keine Quelle erlaubt

'self'

Nur vom Server (und Port) erlaubt von dem die Seite geladen wurde.

'unsafe-inline'

Erlaubt inline Javascripts oder Stylesheets, nicht empfohlen. Siehe Besonderheiten bei Scripts

'unsafe-eval'

Erlaub eval in Javascripts, nicht empfohlen. Siehe Besonderheiten bei Scripts

'scrict-dynamic'

Vertraut scripts die von einem nachgeladenen Javascript geladen wurden

URL

Erlaub diese Quelle z.b. http://www.google.com es sind auch platzhalter möglich z.b. *.facebook.com

https:

Nur über HTTPS erlaubt

data:

URIs wie base64 encoded Bilder

blob:

Erlaubt blob URIs z.b. generierte Bilder

Besonderheiten bei Scripts/Stylesheets

Die werte 'unsafe-inline' und 'unsafe-eval' tragen schon im Name das sie unsicheres Ausführen von inline scripts bzw. eval erlauben.

'unsafe-eval'

Erlaubt die Ausführung von dynamische generiertem Code. Dies ist nicht zu empfehlen bei einige älteren Javascript Libraries/Jquery Plugins aber notwendig.

'unsafe-inline'

Erlaubt Inline-Code innerhalb einer HTML Seite (<script> bzw <style>) und den direkten Aufruf von Eventhandlern mit html Attributen wie onclick.

Benötigt man Inline scripts oder stylesheets kann man die Verwendung mit einem Hash oder Nonce absichern.

Entfernt man den Wert 'unsafe-inline' und ruft eine Seite mit Inline Script auf erhält man eine Fehlermeldung in der Developer Console. Diesen kann man direkt in der Policy angeben ….;script-src 'sha256-xxxxxxx'- Empfehlenswert ist das nur wenn sich das Script nicht ändert.

Bei dynamisch generierten Script-Blöcken lässt sich auch eine sogenannt nonce angeben die eine (jedes mal neu) zufällig generierte Zahl ist und die die der CSP und im Script tag gleich sein muss. BSP:

Content-Security-Policy: …. Script-src 'nonce-123452020'
<script nonce='123452020'>….</script>

 

Policy Testen

Möchte man die Policy erstmal testen (was unbedingt empfohlen ist). Kann man statt dem Header Content-Security-Policy den Header Content-Security-Policy-Report-Only angeben und gibt dann über report-uri eine Url an an die ein Browser Informationen über eine Resourcen blockierung sendet.

Bsp:

Content-Security-Policy: default-src 'self' ; report-url  /report.php

In PHP könnte man die Daten z.b. so verarbeiten: 

$data = file_get_contents('php://input');
if ($data = json_decode($data)) {
// Verarbeiten oder z.b. per email senden
mail("me@home.de","csp report",$data);
}

Weitere Informationen zu CSP

  • Referenz bei Mozilla Developer Network (englisch)
  • Wtf CSP Infos zu CSP Reports und was sie bedeuten