Cross-Site-Scripting (XSS) schädliche Skripts in eine Webanwendung einschleusen. die größten Schwachstellen im Web.
Content Security Policy (CSP)
bietet eine zusätzliche Sicherheitsebene zur Vermeidung von XSS. So konfigurieren Sie eine CSP:
fügen Sie den Content-Security-Policy
-HTTP-Header einer Webseite hinzu und legen Sie Werte fest,
welche Ressourcen der User-Agent
für diese Seite laden kann.
Auf dieser Seite wird erläutert, wie Sie mit einer auf Nonces oder Hashes basierenden CSP anstelle der gängigen CSPs, die auf Host-Zulassungslisten basieren, da sie in den meisten Konfigurationen umgangen werden können.
Schlüsselbegriff: Eine Nonce ist eine Zufallszahl, die nur einmal verwendet wird und mit der Sie eine
<script>
-Tag als vertrauenswürdig eingestuft.
Schlüsselbegriff: Eine Hash-Funktion ist eine mathematische Funktion, die eine Eingabe umwandelt.
Wert in einen komprimierten numerischen Wert umgewandelt, der als Hash bezeichnet wird. Sie können ein Hash
(z. B. SHA-256), um eine Inline-
<script>
-Tag als vertrauenswürdig eingestuft.
Eine Content Security Policy, die auf Nonces oder Hashes basiert, strikte CSP. Wenn eine Anwendung eine strikte CSP verwendet, können Angreifer, die HTML finden, können Injection-Fehler den Browser in der Regel nicht zwingen, bösartige Skripts in einem angreifbaren Dokument. Das liegt daran, dass eine strikte CSP ermöglicht gehashte Skripts oder Skripts mit dem korrekten Nonce-Wert, der auf der ein, damit Angreifer das Skript nur ausführen können, wenn sie die korrekte Nonce kennen für eine bestimmte Antwort.
Warum sollten Sie eine strikte CSP verwenden?
Wenn Ihre Website bereits eine CSP mit dem Format script-src www.googleapis.com
hat,
ist das wohl nicht effektiv bei websiteübergreifenden. Diese Art von CSP wird als
CSPs auf der Zulassungsliste Sie erfordern viel Anpassung und können
von Angreifern umgangen werden.
Mit strikten CSPs, die auf kryptografischen Nonces oder Hashes basieren, vermeiden Sie diese Schwierigkeiten.
Strenge CSP-Struktur
Eine grundlegende strenge Content Security Policy verwendet eine der folgenden HTTP-Antworten Header:
Nonce-basierte strikte CSP
Content-Security-Policy:
script-src 'nonce-{RANDOM}' 'strict-dynamic';
object-src 'none';
base-uri 'none';
Hash-basierte strikte CSP
Content-Security-Policy:
script-src 'sha256-{HASHED_INLINE_SCRIPT}' 'strict-dynamic';
object-src 'none';
base-uri 'none';
Die folgenden Eigenschaften machen eine CSP wie diese „strikt“ und damit sicher:
- Sie verwendet die Nonces
'nonce-{RANDOM}'
oder die Hashes'sha256-{HASHED_INLINE_SCRIPT}'
um anzugeben, mit welchen<script>
-Tags der Entwickler der Website vertraut. im Browser des Nutzers. - Er legt
'strict-dynamic'
fest. den Aufwand für die Bereitstellung einer Nonce- oder Hash-basierten CSP durch das automatische das Ausführen von Skripts ermöglicht, die von einem vertrauenswürdigen Skript erstellt werden. Dies gilt auch für ermöglicht die Nutzung der meisten JavaScript-Bibliotheken und -Widgets von Drittanbietern. - Er basiert nicht auf URL-Zulassungslisten und beeinträchtigt daher nicht Gängige Umgehungen der CSP.
- Nicht vertrauenswürdige Inline-Skripts wie Inline-Event-Handler oder
javascript:
werden blockiert. URIs. object-src
wird eingeschränkt, gefährliche Plug-ins wie Flash zu deaktivieren.base-uri
wird eingeschränkt, das Einfügen von<base>
-Tags zu blockieren. Dadurch wird verhindert, und Angreifer daran hindern, den Speicherort von Skripts zu ändern, die von relativen URLs geladen werden.
Eine strikte CSP verwenden
Für eine strikte CSP müssen Sie Folgendes tun:
- Entscheiden Sie, ob Ihre Anwendung eine Nonce- oder Hash-basierte CSP festlegen soll.
- Kopieren Sie die CSP aus dem Abschnitt Strikte CSP-Struktur und legen Sie sie fest. in Ihrer Anwendung als Antwortheader.
- Refaktorieren von HTML-Vorlagen und clientseitigem Code, um Muster zu entfernen, die nicht mit der CSP kompatibel.
- Stellen Sie Ihre CSP bereit.
Sie können Lighthouse
(Version 7.3.0 und höher mit dem Flag --preset=experimental
) Best Practices-Prüfung
um zu prüfen, ob Ihre Website eine CSP hat und
streng genug, um gegen XSS wirksam zu sein.
Schritt 1: Entscheiden, ob Sie eine Nonce- oder Hash-basierte CSP benötigen
So funktionieren die beiden Arten strikter CSPs:
Nonce-basierte CSP
Bei einer nonce-basierten CSP generieren Sie eine Zufallszahl zur Laufzeit und fügen sie in und mit jedem Skript-Tag auf Ihrer Seite verknüpfen. Ein Angreifer dürfen kein schädliches Skript in eure Seite einfügen oder ausführen, die richtige zufällige Zahl für dieses Skript. Dies funktioniert nur, wenn die Zahl nicht erraten lassen und für jede Antwort zur Laufzeit neu generiert.
Verwende eine nonce-basierte CSP für HTML-Seiten, die auf dem Server gerendert werden. Für diese Seiten können Sie für jede Antwort eine neue Zufallszahl erstellen.
Hash-basierte CSP
Bei einer hashbasierten CSP wird der Hash aller Inline-Skript-Tags dem CSP hinzugefügt. Jedes Skript hat einen anderen Hash. Ein Angreifer kann keine bösartigen da der Hash-Wert des Skripts im CSP, damit sie ausgeführt werden kann.
Verwenden Sie eine hashbasierte CSP für HTML-Seiten, die statisch bereitgestellt werden oder für Seiten, die im Cache gespeichert. Sie können z. B. eine hashbasierte CSP für Single-Page-Web- Anwendungen, die auf Frameworks wie Angular, React oder anderen basieren, statisch ohne serverseitiges Rendering bereitgestellt werden.
Schritt 2: Strenge CSP festlegen und Skripts vorbereiten
Beim Einrichten einer CSP haben Sie mehrere Möglichkeiten:
- Nur-Bericht-Modus (
Content-Security-Policy-Report-Only
) oder Erzwingungsmodus (Content-Security-Policy
). Im Modus „Nur Berichterstellung“ blockiert die CSP damit nichts beschädigt wird. Sie sehen aber Fehler und erhalten für alles, was blockiert worden wäre. Vor Ort, wenn Sie CSP festlegen, spielt das keine Rolle, denn beide Modi zeigen an, in der Browserkonsole angezeigt. Wenn ja, können Sie mit dem Erzwingungsmodus Ressourcen, die vom CSP-Entwurf blockiert werden, da das Blockieren einer Ressource nicht funktioniert. Der Nur-Bericht-Modus wird später am nützlichsten (siehe Schritt 5). - Header oder HTML-
<meta>
-Tag. Für die lokale Entwicklung kann das Tag<meta>
ist sehr praktisch, um die CSP zu optimieren und schnell zu sehen, wie sich das auf Ihre Website auswirkt. Allerdings gilt: <ph type="x-smartling-placeholder">- </ph>
- Wenn Sie die CSP später in der Produktion bereitstellen, sollten Sie sie so festlegen: einem HTTP-Header.
- Wenn Sie für die CSP den Modus „Nur Berichterstellung“ verwenden möchten, müssen Sie sie als , da CSP-Meta-Tags den Berichtsmodus nicht unterstützen.
Lege die folgende Content-Security-Policy
-HTTP-Antwort fest:
in Ihrer Anwendung ein:
Content-Security-Policy: script-src 'nonce-{RANDOM}' 'strict-dynamic'; object-src 'none'; base-uri 'none';
Nonce für CSP generieren
Eine Nonce ist eine Zufallszahl, die nur einmal pro Seitenaufbau verwendet wird. Nonce-basierte Die CSP kann XSS nur abschwächen, wenn Angreifer den Nonce-Wert nicht erraten können. A Die CSP-Nonce muss Folgendes sein:
- Einen kryptografisch starken Zufallswert (idealerweise 128 oder mehr Bit)
- Für jede Antwort neu generiert
- Base64-codiert
Hier sind einige Beispiele dafür, wie Sie eine CSP-Nonce in serverseitigen Frameworks hinzufügen:
- Django (Python)
- Express (JavaScript):
const app = express(); app.get('/', function(request, response) { // Generate a new random nonce value for every response. const nonce = crypto.randomBytes(16).toString("base64"); // Set the strict nonce-based CSP response header const csp = `script-src 'nonce-${nonce}' 'strict-dynamic'; object-src 'none'; base-uri 'none';`; response.set("Content-Security-Policy", csp); // Every <script> tag in your application should set the `nonce` attribute to this value. response.render(template, { nonce: nonce }); });
<script>
-Elementen ein nonce
-Attribut hinzufügen
Bei einer nonce-basierten CSP muss jedes <script>
-Element
haben ein nonce
-Attribut, das mit der zufälligen Nonce übereinstimmt
Wert, der im CSP-Header angegeben ist. Alle Skripts können dieselben
Nonce. Der erste Schritt besteht darin, diese Attribute allen Skripts hinzuzufügen, damit das
Die CSP lässt sie zu.
Lege die folgende Content-Security-Policy
-HTTP-Antwort fest:
in Ihrer Anwendung ein:
Content-Security-Policy: script-src 'sha256-{HASHED_INLINE_SCRIPT}' 'strict-dynamic'; object-src 'none'; base-uri 'none';
Für mehrere Inline-Skripts lautet die Syntax wie folgt:
'sha256-{HASHED_INLINE_SCRIPT_1}' 'sha256-{HASHED_INLINE_SCRIPT_2}'
Quellskripte dynamisch laden
CSP-Hashes werden browserübergreifend nur für Inline-Skripts unterstützt. Sie müssen alle Drittanbieter-Skripts dynamisch mit einem Inline-Skript laden. Hashes für Quellskripts werden in Browsern nicht gut unterstützt.
<ph type="x-smartling-placeholder"><script> var scripts = [ 'https://example.org/foo.js', 'https://example.org/bar.js']; scripts.forEach(function(scriptUrl) { var s = document.createElement('script'); s.src = scriptUrl; s.async = false; // to preserve execution order document.head.appendChild(s); }); </script>
<script src="https://example.org/foo.js"></script> <script src="https://example.org/bar.js"></script>
Überlegungen beim Laden von Skripts
Im Beispiel für ein Inline-Script wird s.async = false
hinzugefügt,
foo
wird vor bar
ausgeführt, auch wenn
bar
wird zuerst geladen. In diesem Snippet: s.async = false
blockiert den Parser nicht, während die Skripts geladen werden, da die Skripts
dynamisch hinzugefügt werden. Der Parser stoppt nur, während die Skripts ausgeführt werden, wie:
würde dies für async
Scripts gelten. Mit diesem Snippet
Hinweis:
-
Es kann sein, dass eines oder beide Skripts ausgeführt werden, bevor das Dokument abgeschlossen ist.
wird heruntergeladen. Wenn Sie möchten, dass das Dokument fertig ist,
Skripts ausgeführt werden, warten Sie auf das
DOMContentLoaded
-Ereignis, bevor hängen Sie die Skripts an. Wenn dies ein Leistungsproblem verursacht, Wenn der Download von Skripts nicht früh genug beginnt, verwenden Sie Tags zum Vorabladen früher auf der Seite. -
defer = true
macht nichts. Falls nötig das Skript manuell bei Bedarf ausführen.
Schritt 3: HTML-Vorlagen und clientseitigen Code refaktorieren
Inline-Event-Handler (z. B. onclick="…"
, onerror="…"
) und JavaScript-URIs
(<a href="javascript:…">
) können zum Ausführen von Skripts verwendet werden. Das bedeutet, dass ein
kann ein Angreifer, der einen XSS-Fehler findet, diese Art von HTML einschleusen und
JavaScript Bei einer Nonce- oder Hash-basierten CSP ist die Verwendung dieser Art von Markup verboten.
Wenn auf deiner Website eines dieser Muster verwendet wird, musst du es in sicherere
Alternativen.
Wenn Sie die CSP im vorherigen Schritt aktiviert haben, sehen Sie CSP-Verstöße in wenn die CSP ein inkompatibles Muster blockiert.
<ph type="x-smartling-placeholder">In den meisten Fällen lässt sich das Problem ganz einfach beheben:
Inline-Event-Handler refaktorieren
<span id="things">A thing.</span> <script nonce="${nonce}"> document.getElementById('things').addEventListener('click', doThings); </script>
<span onclick="doThings();">A thing.</span>
javascript:
URIs refaktorieren
<a id="foo">foo</a> <script nonce="${nonce}"> document.getElementById('foo').addEventListener('click', linkClicked); </script>
<a href="javascript:linkClicked()">foo</a>
eval()
aus JavaScript entfernen
Wenn Ihre Anwendung eval()
zum Konvertieren von JSON-String-Serialisierungen in JS verwendet
-Objekten enthält, sollten Sie diese Instanzen in JSON.parse()
refaktorieren.
schneller.
Wenn Sie nicht alle Verwendungen von eval()
entfernen können, können Sie trotzdem eine strikte nonce-basierte Verwendung festlegen
CSP, aber Sie müssen das CSP-Keyword 'unsafe-eval'
verwenden,
ist etwas weniger sicher.
Diese und weitere Beispiele für solche Refaktorierungen finden Sie in dieser strengen CSP. codelab:
Schritt 4 (optional): Fallbacks hinzufügen, um alte Browserversionen zu unterstützen
Wenn ältere Browserversionen unterstützt werden müssen, gehen Sie so vor:
- Wenn du
strict-dynamic
verwendest, musst duhttps:
als Fallback für frühere Versionen hinzufügen Versionen von Safari. Dabei gilt Folgendes: <ph type="x-smartling-placeholder">- </ph>
- Alle Browser, die
strict-dynamic
unterstützen, ignorieren dashttps:
-Fallback. Dadurch wird die Richtlinie nicht weniger streng. - In alten Browsern können extern generierte Skripts nur geladen werden, wenn sie von
einem HTTPS-Ursprung. Das ist weniger sicher als eine strikte CSP,
verhindert einige häufige XSS-Ursachen wie das Einschleusen von
javascript:
-URIs.
- Alle Browser, die
- Um die Kompatibilität mit sehr alten Browserversionen (mindestens 4 Jahre) sicherzustellen, können Sie
unsafe-inline
als Fallback.unsafe-inline
wird von allen aktuellen Browsern ignoriert wenn eine CSP-Nonce oder -Hash vorhanden ist.
Content-Security-Policy:
script-src 'nonce-{random}' 'strict-dynamic' https: 'unsafe-inline';
object-src 'none';
base-uri 'none';
Schritt 5: CSP bereitstellen
Nachdem Sie bestätigt haben, dass Ihre CSP keine legitimen Skripts in Ihrem Entwicklungsumgebung haben, können Sie Ihre CSP zuerst in der Staging-Umgebung und dann in Ihrem Produktionsumgebung:
- (Optional) Stellen Sie die CSP mithilfe des
Content-Security-Policy-Report-Only
-Header. Der Nur-Bericht-Modus ist nützlich, eine potenziell funktionsgefährdende Änderung wie eine neue CSP in der Produktion zu testen, CSP-Einschränkungen durchzusetzen. Im Modus „Nur Berichterstellung“ werden sich auf das Verhalten Ihrer App auswirken, der Browser generiert jedoch weiterhin Konsolenfehler. und Verstöße melden, wenn Muster erkannt werden, die mit Ihrer CSP nicht kompatibel sind, damit Sie sehen, was für Ihre Endnutzer nicht gut funktioniert hätte. Weitere Informationen Weitere Informationen zur Reporting API - Wenn Sie sicher sind, dass Ihre
CSP keine Unterbrechung für Ihre Website
Stellen Sie die CSP mit dem Antwortheader
Content-Security-Policy
bereit. Mi. empfehlen wir, die CSP serverseitig mit einem HTTP-Header einzurichten, als ein<meta>
-Tag. Nachdem Sie diesen Schritt abgeschlossen haben, beginnt Ihre CSP um Ihre App vor XSS zu schützen.
Beschränkungen
Eine strikte CSP bietet in der Regel eine starke zusätzliche Sicherheitsebene,
XSS zu mindern. In den meisten Fällen reduziert die CSP die Angriffsfläche deutlich, indem
gefährliche Muster wie javascript:
-URIs abgelehnt. Je nach Typ des
der verwendeten CSP (Nonces, Hashes, mit oder ohne 'strict-dynamic'
), gibt es
gibt es Fälle, in denen die CSP Ihre App nicht auch schützt:
- Wenn Sie ein Script Nonce nutzen, aber direkt in den Textkörper oder die
src
-Parameters dieses<script>
-Elements. - Bei Einschleusungen in die Speicherorte dynamisch erstellter Skripts
(
document.createElement('script')
), auch in Bibliotheksfunktionen diescript
-DOM-Knoten basierend auf den Werten ihrer Argumente erstellen. Dieses enthält einige gängige APIs wie.html()
von jQuery sowie.get()
und.post()
in jQuery < 3.0 - Vorlageneinschleusungen in alten AngularJS-Anwendungen Ein Angreifer die in eine AngularJS-Vorlage eingefügt werden kann, Beliebiges JavaScript ausführen.
- Wenn die Richtlinie
'unsafe-eval'
enthält, Einschleusungen ineval()
,setTimeout()
und einige andere selten verwendete APIs.
Entwickler und Security Engineers sollten diese Mustern bei Codeüberprüfungen und Sicherheitsaudits. Weitere Informationen finden Sie diese Fälle in Content Security Policy: A Successful Mess Between Härtung und Risikominderung.