Facebook
Twitter
Google+
Kommentare
0

Die Reporting-Funktion der Content-Security-Policy (CSP)

CSP hatte ich vor fast 2 Jahren bereits vorgestellt, mittlerweile hat es eine gute Verbreitung gefunden, sodass wir uns nochmals die Details anschauen. CSP ist ein Header, den der Server an den Browser schickt, und darin festlegt, von wo Javascripte, Bilder, CSS, Media-Dateien und mehr geladen werden dürfen. Mit sinnvollen Einstellungen ist es möglich, Cross Site Scripting (XSS) sowie Clickjacking zu verhindern, eine dieser essenziell wichtigen Einstellungen ist das Verbot von Inline-Javascript. Falls also ein Angreifer Javascript beispielsweise in die Datenbank einfügen kann, und bei der Ausgabe nicht oder falsch escaped wird, wird das Inline-Javascript das der Angreifer platziert hat nicht ausgeführt, XSS ist effektiv unterbunden.

In der Apache Konfiguration kann das beispielsweise so aussehen:

<VirtualHost *:80>
    DocumentRoot /path/to/wwwroot
    ServerName domain.de

    Header add X-Content-Security-Policy "allow 'self'; img-src images.domain.de; script-src static.domain.de;"
</VirtualHost>

oder hier mittels PHP gesetzt:

<?php
header("X-Content-Security-Policy: allow 'self'; img-src images.domain.de; script-src static.domain.de;");

Sollten nun Bilder oder Javascripte eingebunden sein die nicht von den angegebenen Domains kommen wird der Browser sie blockieren und nicht laden. Es gibt neben img-src und script-src auch noch frame-src, xhr-src und weitere.

Wir können nun also alle gültigen Quellen für die externen Ressourcen definieren. Ein hilfreiches Zusatzfeature ist das Reporting, das den Browser anweist, im Falle einer CSP-Verletzung eine bestimmte URL aufzurufen. Es ist auch möglich, nur das Reporting zu aktivieren. Falls also eine unerwartete Ressource geladen wird von einem fremden Server, können wir Alarm schlagen und das Problem analysieren und beseitigen. Ein Reporting-Header sieht beispielsweise so aus:

<?php
header("X-Content-Security-Policy-Report-Only: allow 'self'; img-src images.domain.de; script-src static.domain.de; report-uri /violation.php");

Der Header-Name hat sich leicht geändert, eine Reporting-URI ist hinzugekommen, ansonsten ist alles gleich geblieben. Im Unterschied zum normalen Header sorgt der Report-Only-Header dafür dass nichts blockiert wird, nur die Verletzungen werden gemeldet. Ideal falls man nur XSS entdecken möchte, es ist auch hilfreich wenn man gerade den richtigen CSP-Header erstellt und produktiv schaltet, denn man kann beide Header senden, dann wird blockiert und reported. Eigentlich sollte der Reporting-Only Header immer da sein, um Rückmeldungen zu erhalten und auf Bedrohungen reagieren zu können.

Wie sieht nun die violation.php aus?

<?php
$json = file_get_contents('php://input');
if ($json === false) {
    throw new Exception('Bad Request');
}

$csp = json_decode($json, true);
if (is_null($csp)) {
    throw new Exception('Bad JSON Violation');
}

$msg = "Request: ".$csp['csp-report']['request']."\n".
       "Request: ".$csp['csp-report']['blocked-uri']."\n".
       "Request: ".$csp['csp-report']['violated-directive'];
// log or mail $msg now

Die Reporting-Informationen kommen als RAW POST JSON Daten. Wir lesen also von der Standard-Eingabe, JSON-decodieren den Text und loggen oder versenden dann die wichtigen Informationen per E-Mail. So sind wir immer auf dem aktuellen Stand bezüglich der CSP-Verstöße.

Hier noch ein Beispiel, und wie es im Firebug dargestellt wird:

<?php
header("X-Content-Security-Policy: allow 'self'; img-src images.domain.de; script-src static.domain.de");
header("X-Content-Security-Policy-Report-Only: allow 'self'; img-src images.domain.de; script-src static.domain.de; report-uri /violation.php");
?>
<html>
    <head>
        <script type="text/javascript">
            alert('CSS');
        </script>
    </head>
    <body>
        <img src="http://www.phpgangsta.de/wp-content/uploads/update-300x225.jpg" />
    </body>
</html>

Die Webseite bleibt komplett weiß, weder das Javascript wird ausgeführt noch das Bild wird angezeigt.

flattr this!

Über den Autor

PHP Gangsta

Der zweitgrößte deutsche, eher praxisorientierte PHP-Blog von Michael Kliewe veröffentlicht seit Mitte 2009 Artikel für Fortgeschrittene.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen