Generieren von CSP-Hashes über die CLI oder PHP

Beitrag vom Januar 2025 aus dem Bereich Security von Arthur Weder

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.

Generieren von CSP-Hashes über die CLI oder PHP

Es existieren verschiedene Möglichkeiten um an den Hash zu gelangen.

In der Browser console bei aktiviertem CSP

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.

webbasiertes Tool

Tools zum Generieren von CSP-Hashes sind zu finden unter: https://www.google.com/search?q=sha256+generator

über die CLI – erster Versuch

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.

mittels php

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.

Lösung:

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=

Verwendung:

CSP Anweisung:

Content-Security-Policy: default-src 'self'; script-src 'sha256-5jFwrAK0UV47oFbVg/iCCBbxD8X1w+QvoOUepu4C2YA='

Das inline Script:

<script>alert(1);</script>

Passende Beiträge aus dem Bereich Security

Sicherer Umgang mit SVG-Dateien

Sicherer Umgang mit SVG-Dateien

Als Website-Betreiber oder Entwickler trägst du die Verantwortung, deine Nutzer und deine Anwendung vor potenziellen Si...

Website-Skripte mit CSP, Hashes und Nonces schützen

Website-Skripte mit CSP, Hashes und Nonces schützen

XSS-Angriffe (Cross-Site-Scripting) zählen zu den häufigsten Bedrohungen im Internet. Dabei versuchen Angreifer, unsic...

Sitzungsfixierung - Cookie-Jar-Overflow-Angriffe

Sitzungsfixierung - Cookie-Jar-Overflow-Angriffe

Auf den ersten Blick könnte man meinen, dass Angreifer mit Cross-Site Scripting (XSS) problemlos Session-Cookies stehle...