Zur Übersicht

Wie kann man die Content Security Policy vor dem Einsatz testen?

Um herauszufinden, ob mit der neu eingerichteten Content Security Policy versehentlich etwas durch den Browser blockiert wird, das aber auf der Website benötigt wird, gibt es das Reporting-Feature.

Lukas Bildstein
Lukas Bildstein Aktualisiert am 2. Juni 2022
content-security-policy-teil3

Eine Beispielkonfiguration - Content-Security-Policy-Report-Only

Die Idee hinter der Content-Security-Policy im Report-Only Modus ist, dass die Content Security Policy  geprüft werden kann, bevor diese “scharf” gestellt wird. Der Browser sendet damit eine Nachricht an einen API-Endpunkt, anstatt eine Ressource zu blockieren. Konfiguriert werden kann das Reporting jedoch nur als http-Header und nicht in einem Meta-Tag. 

Content-Security-Policy: script-src ‘self’ https://code.jquery.com; 
style-src ‘self’; 
report-uri /api/csp-reports

Der Content-Security-Policy-Report-Only http-Header unterstützt die gleichen Direktiven wie der Content-Security-Policy http-Header.

Hinzu kommt am Ende die report-uri mit der angegeben wird, wohin der Browser die Nachrichten senden soll. An dieser URI muss dann ein API-Endpunkt bereitgestellt werden, mit dem die Nachrichten empfangen und zur späteren Auswertung geloggt werden. Der Browser schickt die Nachricht als http-POST-Request mit einem JSON-Body an die angegebene URI.

Wenn der Report-Only http-Header für die Domäne my-page.com konfiguriert ist und auf my-page.com/news eine JavaScript-Datei geladen wird, die durch die Content Security Policy blockiert wird, enthält der mitgesendete Body beispielsweise folgende Daten:

{
  "csp-report": {
    "document-uri": "https://my-page.com/news",
    "referrer": "",
    "blocked-uri": "https://newsviewer.com/js/newsviewer.js",
    "violated-directive": "script-src ‘self’ https://code.jquery.com",
    "original-policy": "script-src ‘self’ https://code.jquery.com; style-src ‘self’",
    "disposition": "report",
    ...
  }
}
Beispiel für den Body eines POST-Requests durch die CSP-Report-Funktion

JSON-Body

Der http-POST-Request mit diesem JSON-Body wird vom Browser durch die eingestellte report-uri /api/csp-reports an die Adresse my-page.com/api/csp-reports gesendet.

Der JSON-Body zeigt, dass ein User die Seite https://my-page.com/news besucht hat (“document-uri”). Dabei wurde versucht, die Datei https://newsviewer.com/js/newsviewer.js zu laden (“blocked-uri”). Diese soll in unserem Szenario dafür verantwortlich sein, die Newsbeiträge auf der Seite schön anzuzeigen. Die JavaScript-Datei wird dafür benötigt und ist von den Developern erwünscht. Die Datei wird jedoch blockiert durch die Direktive script-src ‘self’ https://code.jquery.com (“violated-directive”). Diese legt fest, dass JavaScript-Dateien nur von der eigenen Origin (also https://my-page.com) und von https://code.jquery.com geladen werden dürfen. Da keine der Einstellungen für die https://newsviewer.com/js/newsviewer.js zutrifft, würde die eigentlich benötigte JavaScript-Datei bei der Verwendung der CSP blockiert werden. 

Glücklicherweise sehen die News für den Besucher noch in Ordnung aus, da wir erst im Report-Only Modus sind und der Browser somit statt Blockieren nur eine Benachrichtigung an uns sendet. Wir wissen jetzt also, dass eine zusätzliche Ausnahme für https://newsviewer.com/js/newsviewer.js zur CSP hinzugefügt werden muss, damit beim “scharfstellen” der CSP das benötigte JavaScript nicht blockiert wird und die Newsseite somit noch richtig funktioniert. Die CSP wird dementsprechend angepasst - damit sollten keine weiteren Reports für die vorher blockierte newsviewer.js gesendet werden.

Content-Security-Policy-Report-Only: script-src ‘self’ https://code.jquery.com https://newsviewer.com/js/newsviewer.js; style-src ‘self’; report-uri /api/csp-reports

Vom Reporting zum Blocking

Für die Bereitstellung des Endpunktes, an den der Browser die Nachrichten sendet, und das zugehörige Logging, ist man als Server-Admin oder Developer selbst verantwortlich. Zu beachten ist, dass der Report nur gesendet wird, wenn die entsprechende Seite besucht wird und dort auch etwas blockiert wird. Wenn my-page.com/news nie besucht wird, wird auch kein Report gesendet. Somit fällt dann auch nicht auf, dass fälschlicherweise die newsviewer.js-Datei blockiert wird.

Sobald mit dem Report-Only die Seite mit der gewünschten Content Security Policy für beispielsweise 2 Wochen beobachtet wird und so sichergestellt wird, dass keine benötigten Ressourcen blockiert werden, kann die Content Security Policy scharfgestellt werden durch die Änderung der Konfiguration als http-Header:

Content-Security-Policy: script-src ‘self’ 
https://code.jquery.com https://newsviewer.com/js/newsviewer.js; style-src ‘self’

Bzw. als Meta-Tag:
<meta http-equiv="Content-Security-Policy" content="script-src ‘self’ https://code.jquery.com https://newsviewer.com/js/newsviewer.js; style-src ‘self’">

Blocking und Reports parallel

Falls zusätzlich zum Blocking weiterhin Reports
versendet werden sollen, kann auch beim 
Content-Security-Policy http-Header die Report-URI 
angehängt werden (nur beim 
http-Header und nicht beim Meta-Tag verfügbar):
 

Content-Security-Policy: script-src ‘self’ https://code.jquery.com https://newsviewer.com/js/newsviewer.js; style-src ‘self’; report-uri /api/csp-reports
lukas-bildstein
Lukas Bildstein
Eine schöne Frontend-Optik hat unseren Developer Lukas schon immer fasziniert. Neben seiner Leidenschaft für Visualisierung, schreibt unser Lockenkopf auch eigene Songs auf seiner E-Gitarre. Sein unverwechselbares Erkennungsmerkmal: ein Bandana!