In den letzten Wochen haben wir in diesem Blog eine ganze Reihe von sicherheitsrelevanten HTTP-Headern behandelt, aber der Chef von allen ist die Content-Security-Policy(CSP). Der Chef, sowohl wegen des Schutzniveaus, das er bietet, aber leider auch wegen der Schwierigkeit, ihn auf Anhieb richtig zu implementieren. Wie bei allen flightPATH-Verkehrsmanagementregeln, die wir kürzlich besprochen haben, verwenden wir sie selbst, um die edgeNEXUS-Website und ihre Besucher zu schützen.
Wir haben die harte Arbeit gemacht und den Schmerz gespürt, damit Sie es nicht tun müssen, aber es ist nicht zu leugnen, dass vor der Umsetzung einige Überlegungen und Planungen erforderlich sind. Aber das ist es wert. Das Konzept hinter dieser Kopfzeile ist ziemlich einfach und ebenso leistungsstark. Kurz gesagt, Sie verwenden ihn, um die zulässige Herkunft von Inhalten festzulegen, die auf Ihrer Website geladen werden dürfen. Dies bietet einen starken Schutz gegen eine Reihe von Code-Injection-Angriffen, die im immer dynamischeren Internet heutzutage weit verbreitet sind, wie Cross Site Scripting (XSS) und Clickjacking.
Zu den kontrollierbaren Inhaltstypen gehören: JavaScript, CSS (ja, CSS kann gefährlich sein), HTML-Frames, Schriftarten, Bilder und einbettbare Objekte wie Java-Applets. Es ist großartig, so viele Optionen zu haben, aber genau hier liegt auch die Schwierigkeit. Die heutigen Websites (einschließlich unserer) enthalten eine Vielzahl dieser Inhaltstypen aus vielen Quellen, und sie alle in einer Richtlinie zu identifizieren und zu berücksichtigen, kann ein ziemliches Unterfangen sein.
Bevor wir uns damit befassen, lassen Sie uns einen Blick auf die Elemente des Header-Wertes werfen und darauf, wie eine Richtlinie aussieht. Wie Sie sehen werden, handelt es sich im Wesentlichen um eine lange Liste von Inhaltstypen (die in diesem Beispiel alle mit -src enden) und den zulässigen Quellen für jeden Typ. Zusammen werden diese als Richtlinien bekannt.
default-src „self“ data:; script-src „self“ „unsafe-inline“; connect-src „self“; img-src „self“ data:; style-src „self“ „unsafe-inline“ data:; font-src „self“ data:; child-src „self“
Es gibt noch weitere Inhaltstypen, die wir berücksichtigen können, aber die oben genannten sind unserer Meinung nach die wichtigsten Richtlinien (basierend auf Risiko und Verbreitung). Hier finden Sie die Details zu den Inhalten, auf die sich jede Richtlinie bezieht;
- default-src – Standardwerte für die meisten (aber nicht alle) Inhaltstypen, wenn nicht später angegeben
- script-src – Erlaubte Quellen für Skripte (einschließlich JavaScript)
- connect-src – Erlaubte Quellen für Verbindungen (wie WebSockets und EventSource, die z.B. bei Chat-Anwendungen verwendet werden)
- img-src – Erlaubte Quellen für Bilder
- style-src – Erlaubte Quellen für CSS
- font-src – Zulässige Quellen für Schriftarten
- child-src – Zulässige Quellen für Frames und iframes
Diese Inhaltstypen und ihre Werte werden durch ein Semikolon voneinander getrennt (abgegrenzt). Jeder Typ kann einen oder mehrere der folgenden Werte haben;
- „keine“ – diesen Inhaltstyp nicht zulassen
- „self“ – erlaubt diesen Inhaltstyp, wenn er direkt von dieser Website stammt (aber nicht von Subdomains)
- unsafe-inline‘ – erlaubt Inline-CSS und JavaScript (dies ist leider sehr verbreitet)
- Daten: – Erlauben Sie Inline-Datenquellen (typischerweise verwendet, um Schriftarten und Bilder inline bereitzustellen, um die Leistung zu verbessern)
- https: – diesen Inhaltstyp nur über HTTPS zulassen
- „unsafe-eval“ – erlaubt das Parsen von Text mit potenziell gefährlichen Methoden, die zur Ausführung von Code führen können
- domain-name – erlaubt diesen Inhaltstyp, wenn er von dem angegebenen domain-name stammt (mit anderen Worten, von einer entfernten Domain) – dies kann mehrfach verwendet werden
- * – beliebige Domäne
Jeder Wert wird durch ein einfaches Leerzeichen abgegrenzt. Die einfachen Anführungszeichen ‚ sind erforderlich, es sei denn, der Wert ist ein Domänenname. Beachten Sie, dass Browsererweiterungen und Plugins ausgenommen sind, da diese als sicher gelten, weil der Benutzer ihnen vertraut (er hat sie ja schließlich installiert).
Das sieht alles ziemlich technisch und komplex aus, aber wenn wir es Schritt für Schritt angehen, können wir ziemlich schnell eine Strategie entwickeln. Lassen Sie uns schnell zwei Beispiele durchgehen. Versuchen wir es zunächst mit einer einfachen internen Website, die über HTTP bedient wird. Das brauchen wir;
- default-src „self“ Daten: – nur Inhalte von unserer eigenen Website zulassen, einschließlich Inline-Objekte
- script-src „self“ „unsafe-inline“ – erlaubt Skripte von unserer eigenen Website, einschließlich Inline-Skripte
- connect-src „self“ – erlaubt Verbindungen von/zu unserer eigenen Website
- img-src „self“ Daten: – Bilder von unserer eigenen Website zulassen, einschließlich Inline-Bilder
- style-src „self“ „unsafe-inline“ data: – CSS von unserer eigenen Website zulassen, einschließlich Inline-Stile
- font-src „self“ Daten: – Schriften von unserer eigenen Website zulassen, einschließlich Inline-Schriften
Der vollständige Header-Wert ist relativ kurz:
default-src „self“ data:; script-src „self“ „unsafe-inline“; connect-src „self“; img-src „self“ data:; style-src „self“ „unsafe-inline“ data:; font-src „self“ data:
Zweitens, eine SSL/TLS-geschützte Website, die Google Analytics (GA), Inline-CSS, Schriftarten und Bilder, CSS von Ihrer Website und Bilder von verschiedenen anderen Websites verwendet. Lassen Sie uns Stück für Stück durchgehen, was wir brauchen (es ist nicht sehr unterschiedlich);
- default-src „self“ data: https: – nur Inhalte von unserer eigenen Website zulassen, einschließlich Inline-Objekte, nur über HTTPS
- script-src „self“ „unsafe-inline“ https: – erlaubt Skripte von unserer eigenen Website, einschließlich Inline-Skripte, nur über HTTPS
- img-src „self“ „unsafe-inline“ \* https: – erlaubt Bilder von jeder Website, einschließlich Inline-Bilder von unserer, nur über HTTPS
- style-src „self“ „unsafe-inline“ https: – nur CSS von unserer eigenen Website zulassen, einschließlich Inline, nur über HTTPS
- font-src „self“ „unsafe-inline“ https: – nur Schriften von unserer eigenen Website zulassen, einschließlich Inline-Schriften, nur über HTTPS
Wenn Sie das alles zusammenzählen, erhalten Sie diese etwas längere Police:
default-src „self“ data: https:; script-src „self“ „unsafe-inline“ *.google-analytics.com https:; img-src „self“ „unsafe-inline“ * https:; style-src „self“ „unsafe-inline“ https:; font-src „self“ „unsafe-inline“ https:
Ziemlich einfach, würde ich sagen. Google war in der Vergangenheit nicht so CSP-freundlich (dieser Header-Wert war früher mindestens doppelt so lang), aber glücklicherweise haben sie in letzter Zeit große Fortschritte gemacht. Sie werden feststellen, dass wir die Domäne *.google-analytics.com nicht als Content-Type-Wert zum script-src hinzufügen mussten, da ihr Code als Inline-Skript ausgeführt wird.
Idealerweise würden Sie eine Richtlinie für jede Seite Ihrer Website erstellen, da die geladenen Ressourcen zweifellos von Seite zu Seite unterschiedlich sind. Dies ist jedoch ziemlich mühsam und es ist viel einfacher, aber dennoch effektiv, eine Richtlinie zu erstellen, die alle möglichen Quellen abdeckt. Die meisten der Beispiele auf unserer GitHub-Seite verfolgen diesen Ansatz, aber es gibt auch eines, wenn Sie bestimmte Seiten stärker schützen möchten.
Zum Testen und zur Fehlerbehebung empfehle ich Ihnen, die Google Chrome Developer Tools zu verwenden. Rufen Sie die betreffende Website auf, drücken Sie F12, klicken Sie auf Netzwerk, stellen Sie sicher, dass Cache deaktivieren aktiviert ist und laden Sie die Seite erneut. Alle Fehler werden deutlich hervorgehoben. Unten in diesem Blog finden Sie einen Bildschirm, der zeigt, was Sie sehen könnten, wenn Ihre Richtlinie unsafe-inline blockiert und Sie Google Analytics verwenden; die Fehlermeldungen sind sehr hilfreich.
Passen Sie Ihre Richtlinie nach Bedarf an und spülen Sie sie aus und wiederholen Sie sie. Idealerweise verwenden Sie dazu einen dedizierten virtuellen Testdienst, auf den die zu testende flightPATH-Regel angewendet wird, der aber ansonsten dieselbe Website bedient, nur über eine andere virtuelle IP, damit Sie während des Tests keine echten Kunden und Klienten beeinträchtigen.
Wie immer liegt der große Vorteil des Einsatzes eines Load Balancer darin, dass wir dies nur an einer zentralen Stelle tun müssen, um alle unsere Server (und Websites) zu schützen. Wir müssen uns nicht auf Entwickler oder Webserver-Neukonfigurationen verlassen. Auf dem edgeNEXUS Load Balancer importieren wir einfach eine automatische jetPACK-Konfigurationsvorlage und weisen dem oder den virtuellen Diensten, die wir schützen möchten, eine flightPATH-Verkehrsregel zu (nach entsprechenden Änderungen).
Die Regel fügt die Kopfzeile nur hinzu, wenn sie nicht vorhanden ist. Sie funktioniert also auch dann, wenn unsere Webserver sie bereits einfügen oder vielleicht nur für bestimmte Seiten einfügen. Diese Regel sollte Teil Ihrer Standardkonfiguration für virtuelle Dienste sein – Sie haben nichts zu verlieren, egal wie die Seite aussieht. Sie können dieses jetPACK und viele andere auf der edgeNEXUS Github-Website herunterladen.
flightPATH ist eine dynamische, ereignisbasierte Regel-Engine, die von edgeNEXUS entwickelt wurde, um IP-, HTTP- und HTTPS-Verkehr mit Lastverteilung intelligent zu manipulieren und zu routen. Sie ist hochgradig konfigurierbar und leistungsstark, aber dennoch sehr einfach zu bedienen.
Diese weiterführenden Links sind es wert, gelesen zu werden, wenn Sie mehr wissen möchten;
http://www.html5rocks.com/en/tutorials/security/content-security-policy/
https://developer.mozilla.org/en/docs/Web/Security/CSP/CSP_policy_directives
http://content-security-policy.com/
https://www.clickintelligence.co.uk/header-response-checker/
In den letzten Wochen haben wir in diesem Blog eine ganze Reihe von sicherheitsrelevanten HTTP-Headern behandelt, aber der wichtigste von ihnen ist die Content-Security-Policy (CSP).