Ich versuche derzeit, auf einer Seite eine Content-Security-Policy im strikt dynamischen Modus einzurichten. Da es sich um eine statische Seite handelt, sind Nonces für mich keine Option, daher versuche ich, Hashes zu verwenden. Ich habe eine Weile gebraucht um herauszufinden, wie ich die Hashes im richtigen CSP-Format in der Befehlszeile generieren kann. Ich habe es schließlich herausgefunden, indem ich verschiedene Informationen zusammengefügt habe, und wollte meine Erkenntnisse hier teilen.
Es existieren verschiedene Möglichkeiten um an den Hash zu gelangen.
Ist CSP mit der Standard-Einstellung Content-Security-Policy: default-src 'self';
aktiviert und die Website integriert Inline-Script-Blöcke, zeigt die Konsole beim Laden der Website einen Fehler an.
Refused to execute inline script because it violates the following Content Security Policy: „default-scr ’self'“.
Either the unsafe-inline keyword, a hash(’sha256-sdfjkhfdkjPsdfdfPsddsP‘), or nonce … is required to enable inline execution.
Tools zum Generieren von CSP-Hashes sind zu finden unter: https://www.google.com/search?q=sha256+generator
Gemäß der script-src-Dokumentation von MDN müssen wir einen „base64-codierten Hash“ generieren
Auf den ersten Blick scheint das nicht so schlimm zu sein. Das ist, was mir zunächst eingefallen ist:
echo -n 'alert(1);' | shasum -a 256 | cut -d' ' -f1 | base64
ZTYzMTcwYWMwMmI0NTE1ZTNiYTA1NmQ1ODNmODgyMDgxNmYxMGZjNWY1YzNlNDJmYTBlNTFlYTZlZTAyZDk4MAo=
Wie Sie jedoch beim Vergleich mit der Ausgabe von ReportURI feststellen werden, ist dies nicht der erwartete Wert.
Beispiel-PHP-Quellcode zum Generieren von CSP-Hashes:
<?php
$alg = 'sha256';
$data = "alert(1);"; # inline JS oder CSS ohne <script> oder <style> Tags
$base64 = base64_encode(hash($alg, $data, true));
echo "$alg-$base64";
# sha256-2saFEHt0PuLirYPF+oVKJcY5vrrl+WqXYIoq3HAH4vr=
?>
Was mir hier auffiel, war das dritte Argument, das an die PHP-Hash-Funktion übergeben wurde. Laut der PHP-Dokumentation:
Wenn auf true
gesetzt, werden rohe Binärdaten ausgegeben. FALSE gibt Hexadezimalzahlen in Kleinbuchstaben aus.
https://www.php.net/manual/en/function.hash.php
Aha! shasum
hat keine rohen Binärdaten ausgegeben, sondern eine Hexadezimaldarstellung.
Soweit ich es der Manpage von shasum
entnehmen konnte, gibt es keine Option zur Ausgabe als Binärdaten, aber diese StackExchange-Antwort brachte mich auf die Idee, xxd zu verwenden.
Der folgende Befehl generiert letztendlich den Hash im richtigen Format zur Verwendung in einem CSP.
echo -n 'alert(1);' | shasum -a 256 | cut -d' ' -f1 | xxd -r -p | base64
Resultat:
5jFwrAK0UV47oFbVg/iCCBbxD8X1w+QvoOUepu4C2YA=
CSP Anweisung:
Content-Security-Policy: default-src 'self'; script-src 'sha256-5jFwrAK0UV47oFbVg/iCCBbxD8X1w+QvoOUepu4C2YA='
Das inline Script:
<script>alert(1);</script>