Content-Security-Policy

Die MSXFAQ besteht nicht nur aus aus lesbarem Text sondern auch einigen versteckten Bestandteilen, die den Browser des Besucher betreffen. Über HTTP-Header und Meta-Tags kann man den Schutz steuern. Ein Feld ist dabei die "Content-Security-Policy", mit der ich als Betreiber vorgeben kann, woher euer Browser zusätzliche Daten nachladen darf. Ganz sicher ist das nicht, denn ein AddOn im Browser, eine Malware als Proxy o.ä. könnte auch diesen Schutz aushebeln, aber er ist besser als nichts.

Standardfunktion

Ohne eine Content-Security-Policy kann ich in einer HTML-Seite weitere Dateien von beliebigen Quellen nachladen, d.h. ich kann Bilder, JavaScript u.a. auch von ganz anderen Webservern nachladen. Viele Webseiten nutzen dies um z.B. Werbenetzwerke einzubinden oder auch statistische Dienste zu integrieren. Auch die Quellen von JavaScript-Code, Bildern, Schriftarten etc. könnten überall auf der Welt liegen. Da macht es natürlich auch Angreifern einfach den Code zu seinen Gunsten zu ändern.

Skript und URLs

Da die MSXFAQ meistens von Administratoren und erschreckend oft von Servern aufgerufen wird, schaue ich schon selbst drauf, dass die Funktion auch im "abgesicherten" Mode eines Browsers oder Blockern weitgehend vorhanden sind. Daher gibt es eigentlich nur ganz wenige Skripte und fast gar keine externe Verweise. Die Skripte sind mit einer Ausnahme auch komplett auf meiner Webseite.

  • Verhinderung gegen IFrame-Einbindung
  • Menü Auf/Zuklapper
    Der Code ist noch drin aber aktuell nicht in Benutzung und daher auskommentiert.
  • Google Analytics
    Dieses Inline-Skript lädt als einziges ein JavaScript von Google nach, welche einige Informationen über sie als Besucher an Google Analytics meldet.
  • YouTube
    Auf einigen Seiten bette ich Videos von meinem YouTube-Kanal ein. Das muss natürlich auch gesondert zugelassen werden
  • JavaScript
    Auf ganz wenigen Seiten, z.B.: ICEWarn Bedeutung, nutze ich JavaScript, die ich anfangs im HTML-Code hinterlegt habe
  • Net at Work Include
    Das kleine Aktionsfeld rechts oben lade ich mir von www.netatwork.de nach, was ich natürlich entsprechend erlauben muss.

Wenn ich nun mit einer "Content-Security-Policy" das Nachladen von unbekannten Quellen blockiere, dann muss ich die erlaubten Quellen aufführen.

META-Tag

Den "Content-Security-Header" kann man als Autor einer Webseite direkt im <HEAD> jeder Seite ihrer Webseite statisch setzen. Das ist für viele Shared-Hosting-Pakete der einzige Weg, wenn Sie keinen Zugriff auf die Konfiguration des WebServers haben.

Alternativ können Sie über PHP den Header ebenfalls setzen, z.B.:

<?php
   header("Content-Security-Policy: default-src 'self'; script-src 'self'");
?>

Das Problem dabei ist, dass die jede Seite anpassen müssen und auch eine Malware die gleichen Veränderungen umsetzen kann. zudem müsste dann jede Webseite durch den PHP-Interpreter laufen und könnte nicht einfach ausgeliefert werden.

HTTP-Header

Daher ist die Auslieferung als HTTP-Header eigentlich immer vorzuziehen. Sie müssen dazu natürlich die htaccess-Datei ihres Apache-Servers oder die Konfiguration des IIS anpassen. Dann aber können Sie auch sicher sein, dass die Richtlinien "sicher" sind, denn die Browser ignorieren die gleichen Einstellungen im <HEAD>-Teil der Seite wenn sie im HTTP-Header gesetzt sind.

Bei der MSXFAQ sende ich daher über die HTACCESS folgenden Header mit: (Umbruch zur Lesbarkeit)

# Apache Content-Security-Policy Header
Header set Content-Security-Policy "default-src 'self' www.netatwork.de;  
                                      style-src 'self' 'unsafe-inline'; 
                                      frame-src 'self' www.youtube.com; img-src 'self' www.netatwork.de https://www.google-analytics.com;  
                                     script-src 'self' 'unsafe-inline' https://www.google-analytics.com https://ssl.google-analytics.com;  
                                    connect-src https://www.google-analytics.com"

Die Bedeutung in Kürze:

  • default-src
    Ich vertraue erst einmal nur den Inhalten meiner eigenen Seite.
  • style-src
    An einigen HTML-Elementen sind manuelle "Style"-Elemente, die ich damit noch zulasse
  • frame-src
    Ich lasse die IFRAME-Einbindungen von YouTube-Videos als auch innerhalb meiner eigenen Seite zu
  • img-src
    Bilder dürfen von der eigenen Seite, aber auch der Infoblock Net at Work als auch Zählpixel von Google kommen
  • script-src
    Skripte kommen von der eigenen Seite oder von Google. Leider musste ich aber auch noch 'unsafe-inline' aktivieren, damit der Aufruf von Google mit den Parametern möglich ist
  • connect-src
    Diese Eintrag ist für Google Analytics ebenfalls erforderlich

Mit der Policy sind viele Angriffsmuster schon erschwert oder unterbunden aber durch das "'unsafe-inline' " im Script-src bleibt eine Lücke, die ich auch noch schließen will. Nur sind das die Parameter für das Google-Script und die Auslagerung muss ich noch machen.

Das bedeutet natürlich auch einen höheren Schutz, weil auch ein Angreifer, der die Inhalte verändern kann. vielleicht nicht die Header anpassen kann.

Kontrolle

Natürlich sollten Sie sicher sein, dass die alle externen Seiten auch korrekte und vollständig angegeben haben. Wenn Sie z.B. den Google Analytics-Zugriff unterbunden haben, oder auch in einer deuteten Version eines JavaScripts andere URLs zum Einsatz kommen, dann fällt das nicht immer sofort auf. Anders kann ich mir den "Einbruch" in Google Analytics auch nicht erklären.

Google hat ja keinen Zugriff auf meine Apache-Logs. Die Tatsache, dass einige Zugriffe dennoch erfasst wurde, liegt wohl an Clients, die mit der Richtlinie nichts anfangen können oder diese ignoriert haben. Ich habe eine Stichprobe gemacht und es hat den Anschein, dass nur noch neuere Browser (Edge 81, Firefox 76, Chrome 81) gemeldet haben.

Sie sollten nach dem Upload der Seite über die Developer Tools kontrollieren, ob es irgendwelche Fehler gibt. Hier sehen Sie eine unpassende Richtlinie.

Hier sollten keine Fehler zur "Content Security Policy directive" erscheinen.

Reporting

Die Direktive zu setzen und selbst zu prüfen ist nur ein Teil der Umsetzung. Die Definition der "Content-Security-Policy" enthält auch die Funktion, eine URL für eine Rückmeldung zu hinterlegen, z.B.:

...; report-uri http://www.msxfaq.de/cspreport.php

Ein Browser, dies korrekt umsetzt, übermittelt dann per HTTP-Post einen Report, der etwas folgende Daten hat:

{
  "csp-report": {
    "document-uri": "http://www.msxfaq.de/index.htm",
    "referrer": "http://badhost.msxfaq.de/",
    "blocked-uri": "http://badhost.msxfaq.de/malware.js",
    "violated-directive": "unsafe-inline' https://www.google-analytics.com https://ssl.google-analytics.com",
    "original-policy": "xxxxx"
  }
}

Diese Daten können Sie so interpretiere, dass ein Anwender von der Seite "http://badhost.msxfaq.de/" auf ihre Seite gekommen ist aber durch eine Lücke es schafft, dass der Client Code von der Malware-Seite nachgeladen hätte. Die "Content-Security-Policy" hat das hier verhindert und auch gemeldet.

Ich habe keine solche Erkennung eingebaut. Wichtig ist dies aber z.B. für Seiten von Banken o.ä. die damit Angriffe erkennen und begegnen können.

Strict-Transport-Security

Es gibt noch weitere Header, die zwar nun nicht direkt mit "content-security-policy" in Zusammenhang stehen aber dennoch die Sicherheit erhöhen können. Wen die Webseite sowieso per HTTPS erreichbar ist, dann kann ich mit der Vorgabe einer "Strict-Transport-Security" die Browser anweisen, dass Sie auch zukünftig immer auf HTTPS bestehen sollen. In der ".HTACCCESS" eines Apache kann ich dazu addieren.

Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"

Der Parameter "includeSubDomains" ist optional und mit max-age ist die Anzahl der Sekunden (31536000= 1 Jahr) gemeint, für die ein Zugriff per HTTPS erforderlich sein. Der Browser merkt sich dann 1 Jahr, das der Zugriff per HTTPS verschlüsselt wurde und auch weiterhin verschlüsselt werden muss.

Diese Einstellung habe ich am 21. Nov 2002 gesetzt

Permission Policy

Relativ neu ist dieser Header und er wird auch noch nicht von allen Browsern ausgewertet. Damit kann ich als Webautor aber beschreiben, welche Funktionen die Webseite auf dem Client benötigt. So wird eine Videokonferenzplattform wie Teams, Zoom, WebEx sicherlich den Zugriff auf Kamera und Mikrofon so ankündigen. Browser können dann sehr früh schon die Einwilligung des Anwenders anfordern und nicht erst, wenn der Code dazu aktiv wird. Da die MSXFAQ nichts davon nutzt und daher auch nicht anfordert, habe ich folgenden Header über die .HTACCESS-Datei addiert, (Umbruch bitte entfernen)

Header set Permissions-Policy "geolocation=(), midi=(), camera=(), usb=(), 
                               magnetometer=(), accelerometer=(), vr=(),
                               speaker=(), ambient-light-sensor=(), gyroscope=(), microphone=()"

Apache Server

Wenn man den Clients auch nicht mehr verraten möchte, welche Serverversion auf dem WebServer aktiv ist, dann kann auch diese Information in der ".HTACCESS" unterdrückt werden.

# Remove server signature in HTTP-Header
ServerSignature Off

Bei mir hat das aber noch nicht gegriffen.

Kontrolle

Es gibt einige Dienste, die eine HTTP-Anfrage an einen Webserver stellen und den Status der Header ausgeben, z.B.


Quelle: https://securityheaders.com/?q=www.msxfaq.de&followRedirects=on  (12 Nov 2020)

Weitere Links