It’s #FrontendFriday – Einsatz der Content Security Policy (CSP)

30.11.2018

Die Content Security Policy (CSP) ist ein Sicherheitskonzept, um Cross-Site-Scripting-Attacken (XSS) und andere Angriffe in Browsern zu verhindern. XSS beschreibt das Einbetten eines schädlichen Codes in einen anderen vermeintlich sicheren Kontext.

Durch die CSP werden beim Ausliefern der Webseite oder Webanwendung zusätzliche Meta-Tags übermittelt, die festlegen, welche „Vorgänge“ verhindert werden sollen. So kann z.B. das Ausführen von JavaScript-Dateien oder das Einbinden von Bildern, wenn diese nicht vom selben Server oder nicht von einer bestimmten Quelle stammen, unterbunden werden. Welche Inhalte gesperrt und welche erlaubt sind, wird durch die Angabe der Content-Security-Policy und dessen Parametern definiert.

Setzen der Content-Security-Policy

Die CSP wird durch die Definition von Parametern in eine Webanwendung integriert. Je nach Art der Parameter kann die Härte der CSP festgelegt werden.

Content-Security-Policy: script-src ’self‘ → Legt fest, dass JavaScript-Dateien nur vom eigenen Server nachgeladen werden dürfen.

Content-Security-Policy: script-src ’self‘ https://apis.google.com → Legt eine Ausnahme fest, sodass nur JavaScript-Dateien des eigenen Servers sowie Inhalte von https://apis.google.com erlaubt sind.

Schleust ein Angreifer z.B. ein Tag wie <script src=“http://evil.com/evil.js“></script> ein, wird dieses Skript nicht ausgeführt, da dies keine zuverlässige Quelle für Skripte darstellt. Der Browser gibt in diesem Fall eine Fehlermeldung aus.

Das „script-src“ steht hierbei für JavaScript-Dateien und wird als Direktive bezeichnet. Diese Direktive kann, je nach Anwendungsfall, unterschiedlich gesetzt und auch kombiniert verwendet werden.

Nach der Angabe der Direktive folgen die Parameter zur Definition der erlaubten Quellen. Hier kann zum Beispiel mit einem * alles erlaubt, mit ’none‘ alles blockiert oder mit ’self‘ das Laden von eigenen Ressourcen erlaubt werden.

Browserunterstützung

Um die Browserunterstützung schon mal vorweg zu nehmen: Für die Content Security Policy muss die Browser Kompatibilität berücksichtigt werden. Eine große Herausforderung ist wie immer der Internet Explorer, für den eigentlich immer ein Sonderfall implementiert werden muss. Eine Übersicht, welche Direktiven von den Browsern unterstützt werden, gibt es hier: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP#Browser_compatibility.

Anwendung der CSP

Variante 1: <meta>-Element in HTML-Code

Durch die Angabe von <meta>-Elementen im Header des HTML-Codes kann definiert werden, wie strikt die Content Security Policy für diese Seite eingestellt werden soll.

<!doctype html>
<head>
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
  <meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
  <meta http-equiv="X-WebKit-CSP" content="default-src 'self'; script-src 'self'">
  <title>CSP nutzende Seite</title>
</head>
<body>
  <h1>Sie sind sicher</h1>
  <p>Dieses Dokument wurde mit einer sehr strikt eingestellten Content Security Policy ausgeliefert.</p>
</body>
</html>

In diesem Beispiel ist die CSP sehr strikt definiert. Durch die Angabe von default-src ’self‘  dürfen zusätzlichen Inhalte grundsätzlich nur geladen werden, wenn diese vom eigenen Server stammen. Die Anweisung script-src ’self‘ definiert, dass nur JavaScript-Datein vom eigenen Server ausgeführt werden dürfen.  Wie so häufig müssen auch hier Sonderfälle für ältere Browser und den IE eingebunden werden. Hierzu sind die Tags mit X-Content-Security-Policy (für die Unterstützung älterer Internet Explorer Versionen) und X-Webkit-CSP (für ältere Versionen von auf Webkit-Engine basierende Browser z.B. Chrome und Safari) angegeben.

Variante 2: Konfiguration des Webservers

Die CSP kann auch über den Webserver gesetzt werden. So werden bei diesem Weg die Parameter im HTTP-Header gesetzt und sie werden über die komplette Webseite hinweg berücksichtigt. Auch hier müssen für den IE und ältere Versionen die Werte X-Content-Security-Policy und X-Webkit-CSP gesetzt werden.

Header set Content-Security-Policy "default-src 'self'"
Header set X-Content-Security-Policy "default-src 'self'"
Header set X-Webkit-CSP "default-src 'self'"

Wie macht das Angular?

Um in einer Angular Anwendung die Content Security Policy zu nutzen, kann die Variante 2 verwendet und der Content-Security-Policy HTTP Header gesetzt werden. Es wird somit serverseitig sichergestellt, dass nur vertrauenswürdige Quellen eingebunden werden. Angular bringt jedoch auch schon einige Features mit. So erkennt Angular beispielsweise unsichere Werte in einer Variable und bereinigt diese automatisch.

export class InnerHtmlBindingComponent {
  // For example, a user/attacker-controlled value from a URL.
  htmlSnippet = 'Template <script>alert("0wned")</script> <b>Syntax</b>';
}

Angular erkennt hier selbständig, dass ein Script-Tag im String enthalten ist und eliminiert die potenzielle XSS Schwachstelle. Hierzu wird der script-Tag entfernt.

Folgende Ausgabe kommt zustande:

Resultat der automatischen Eliminierung einer XSS Schwachstelle durch Angular

Quelle: https://angular.io/guide/security 

Einsatz des DomSanitizer

Um auch im Angular-Code Einschränkungen bzw. Ausnahmen zu definieren, kann der DomSanitizer verwendet werden. Der DomSanitizer stellt Methoden bereit um URLs, Skripte und sonstige Ressourcen explizit als vertrauensvolle Quellen freizugeben. Hier ist es wichtig, dass die korrekte Methode für den Anwendungsfall verwendet wird. Der DomSanitizer stellt folgende Methoden bereit:

  • bypassSecurityTrustHtml
  • bypassSecurityTrustScript
  • bypassSecurityTrustStyle
  • bypassSecurityTrustUrl
  • bypassSecurityTrustResourceUrl

Beispiel:

<h4>An untrusted URL:</h4>
<p><a [href]="dangerousUrl">Click me</a></p>
<h4>A trusted URL:</h4>
<p><a [href]="trustedUrl">Click me</a></p>

Von Angular wird der Inline JavaScript javascript:alert() als potenzielle Schwachstelle erkannt und eliminiert. Durch den Aufruf einer Methode des DomSanitizer kann diese „URL“ als vertrauensvoll eingestuft werden.

constructor(private sanitizer: DomSanitizer) {
  // javascript: URLs are dangerous if attacker controlled.
  // Angular sanitizes them in data binding, but you can
  // explicitly tell Angular to trust this value:
  this.dangerousUrl = 'javascript:alert("Hi there")';
  this.trustedUrl = sanitizer.bypassSecurityTrustUrl(this.dangerousUrl);

Dies führt dazu, dass der zweite Link klickbar und korrekt ausführbar ist. Das Frontend sieht dann so aus:

Alert Box duch eine als trusted URL definierte URL

Quelle: https://angular.io/guide/security 

Fazit

Durch Einsatz von CSP können Cross-Site-Scripting-Attacken abgewehrt werden, indem das Einbinden von Daten von fremden Servern unterbunden wird.  Es macht also durchaus Sinn diese Policy zu verwenden. Es muss jedoch immer mit betrachtet werden, ob auch Ausnahmen definiert werden müssen. Das Einschränken durch die CSP auf bestimmte Quellen, kann nämlich auch unerwünschte Nebeneffekte haben. Welche Direktiven und Parameter verwendet werden müssen und wie strikt die CSP definiert werden muss, ist abhängig von den Sicherheitsbestimmungen bis hin zu den verwendeten Frameworks und Technologien.


Quellen

https://content-security-policy.com/
https://wiki.selfhtml.org/wiki/Sicherheit/Content_Security_Policy
https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
https://angular.io/api/platform-browser/DomSanitizer
https://angular.io/guide/security

Zurück zur Übersicht

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

*Pflichtfelder

*