HSTS & weitere HTTP Security Header aktivieren zum Schutz vor XSS (Cross-Site-Scripting) & Man-in-the-Middle Angriffen

Auch wenn Sie auf Ihrer Website ein SSL-Zertifikat installiert haben und Ihre Website via HTTPS erreichbar ist, ist es technisch immer noch möglich, auf die HTTP-Version Ihrer Website zuzugreifen (auch wenn Sie mit einem 301-Redirect automatisch auf die verschlüsselte HTTPS Version Ihrer Website weiterleiten).

Und „technisch möglich“ heisst, es kann potenziell von Angreifern ausgenutzt werden, um Ihr SSL-Zertifikat zu umgehen (sogenannte „Man-in-the-Middle“ Angriffe).

Was genau macht HSTS?

Ohne jetzt all zu sehr in die technischen Details zu gehen (bei Interesse finden Sie in Google genügend Artikel zum Thema):

Wenn ein Besucher im Browser z.B. google.ch eingibt, wird im Hintergrund zuerst die HTTP Version aufgerufen, welche auf die HTTPS Version weiterleitet. Und genau bei diesem ersten HTTP Aufruf könnte ein Angreifer theoretisch ansetzen, um die Verbindung zu kapern und alle übertragenen Daten abzuhören oder zu verändern.

Zugegeben: Das Risiko ist zwar relativ gering. Aber da die Lösung relativ einfach umzusetzen ist, muss man es ja nicht darauf ankommen lassen 😉

Und die Lösung ist HTTP Strict Transport Security (oder eben kurz „HSTS“).

Wenn HSTS aktiviert ist, dann wird dem Browser mitgeteilt, ausschliesslich die HTTPS Version der Website zu nutzen (und eben nicht darauf zu hören, was die HTTP Version der Website allenfalls zurückgemeldet hat).

HSTS kann also als ein kleines SSL-Upgrade betrachtet werden.

Und es gibt noch weitere „Upgrades“, um die Sicherheit zu erhöhen:

Die 7 HTTP Security Header

Wenn wir schon dabei sind HSTS zu aktivieren, kann man auch gleich noch (einen Teil) der weiteren HTTP Security Header aktivieren.

Davon gibt es insgesamt 7:

  1. Strict-Transport-Security (das ist das HSTS)
  2. X-XSS-Protection
  3. Referrer-Policy
  4. X-Frame-Options
  5. X-Content-Type-Options
  6. Content-Security-Policy
  7. Feature-Policy

Übrigens: Mit diesem Tool können Sie ganz einfach testen, ob und welche HTTP Security Header auf Ihrer Website korrekt aktiviert worden sind (wie man den perfekten Score erreicht, habe ich am Ende des Artikels genauer erklärt): SecurityHeaders.com

Schauen wir uns also die einzelnen HTTP Security Header an:

Wie werden HSTS und die HTTP Security Header aktiviert?

Das kommt grundsätzlich auf den eingesetzten Webserver an. Der am weitesten verbreitete Webserver ist Apache. Und beim Apache können HSTS und die HTTP Security Header ganz einfach in der im Hauptverzeichnis liegenden .htaccess-Datei aktiviert werden.

Hinweis: Es kann bei gewissen Hostern vorkommen, dass die Bearbeitung der .htaccess gesperrt wurde. Im Zweifelsfall müssen Sie also Ihren Hoster kontaktieren.

Und schon einmal eine wichtige Warnung vorab: „Einfach aktiviert“ heisst nicht, dass auch alle HTTP Security Header einfach (sinnvoll) konfiguriert werden können.

In diesem Artikel gebe ich nur eine kurze Übersicht und welche Einstellungen ich warum grundsätzlich empfehlen würde. Wer es genauer wissen will, der sollte die Optionen und Möglichkeiten für die einzelnen Header in Google genauer recherchieren.

Schauen wir uns die HTTP Security Header der Reihe nach an:

#1: Strict-Transport-Security (also HSTS)

Das habe ich zu Beginn des Artikels ausführlich erklärt und kann wie folgt aktiviert werden (natürlich nur aktivieren, wenn die Website auch tatsächlich ein SSL-Zertifikat hat und über HTTPS erreichbar ist):

Header always set Strict-Transport-Security "max-age=15768000" env=HTTPS

Das ist zugleich auch der wichtigste Security Header.

Es gibt noch mehr Optionen, aber für die meisten Websites reicht das aus.

#2: X-XSS-Protection

Die X-XSS-Protection bietet Schutz vor gewissen XSS (Cross Site Scripting) Angriffen.

Es ist kein Allheilmittel, aber es macht Sinn es zu aktivieren, speziell da es etwas sicherer ist, als die im Browser verwendete Standard Option (was ohne „mode=block“ ist und hier genauer erklärt wurde).

Header set X-XSS-Protection "1; mode=block"

#3: Referrer-Policy

Wenn Sie von einer Website A auf die Website B surfen, dann weiss Website B dank dem Referrrer, dass Sie von Website A kommen (die vorherige URL wird also mitgesendet).

Das kann in der heutigen Zeit (Stichwort DSGVO und Datenschutz) problematisch sein, falls Sie eine Website mit sensitiven Themen führen.

Aber:

Ich wäre grundsätzlich vorsichtig mit dieser Option, da es unter Umständen Nebeneffekte haben kann (z.B. kann es Einfluss auf das Google Analytics Tracking sowie ev. auf Affiliate Links haben). Sprich, nur ändern, wenn man genau weiss was man tut.

Darum setze ich persönlich es auch einfach auf die vom Browser sowieso genutzte Standard Einstellung „no-referrer-when-downgrade“. Diese entfernt die Referrer-Information nur, wenn auf eine unverschlüsselte (HTTP) Website verlinkt:

Header set Referrer-Policy: no-referrer-when-downgrade

#4: X-Frame-Options

Diese X-Frame-Options definiert, ob die eigene Website via <iframe> auf fremden Websites eingebunden werden darf.

Das verhindert sogenanntes „Clickjacking“. Eine fremde Website kann dann Ihre Website nicht mehr auf der eigenen Website einbinden.

Ein praktisches Beispiel wäre: Eine Website bindet versteckt Twitter ein. Dann verleitet man den Besucher dazu, irgendwo auf der Website einen Button anzuklicken, der aber im Hintergrund automatisch einen vordefinierten Tweet versendet. Ist der Besucher in seinem Browser in Twitter angemeldet, dann kann so ohne sein Wissen ein Tweet versendet werden (dieses Beispiel ist hier gut beschrieben).

Da Twitter das aber mit dem X-Frame-Options Header verhindert, würde das in der Praxis gar nicht gehen.

Für „normale“ Websites ist Clickjacking aber normalerweise keine Gefahr.

Ausserdem kann man damit auch verhindern, dass der eigene Inhalt via <iframe> „gestohlen“ wird und auf einer fremden Website angezeigt wird. Aber Google ist sehr gut im Erkennen von Duplicate Content und weiss, woher der originale Inhalt kommt. Darum ist das meiner Meinung nach aus SEO Sicht vernachlässigbar (und das häufigere direkte Kopieren lässt sich dadurch sowieso nicht verhindern).

Wichtig: Man muss daran denken, dass gewisse Tools wie z.B. die Web Developer Toolbar vom Google Chrome oder Firefox dann nicht mehr funktionieren.

Kurz gesagt: Der X-Frame-Options Header ist meiner Meinung nach nicht sehr wichtig. Aber da er in den allermeisten Fällen keine Probleme oder Einschränkungen verursacht, kann man ihn mit diesem Code grundsätzlich trotzdem bedenkenlos aktivieren:

Header always append X-Frame-Options SAMEORIGIN

#5: X-Content-Type-Options

Das ist insbesondere eine Gefahr bei Websites, wo Benutzer eigene Dateien hochladen können, die dann wiederum öffentlich von anderen Besuchern angezeigt werden können.

Ein Angreifer kann theoretisch eine (angebliche) .JPG Bild-Datei hochladen. In dieser Bild-Datei steckt jedoch eigentlich eine HTML-Datei, mit der via XSS (Cross-Site-Scripting) Schadcode ausgeführt werden soll.

Wenn jetzt das Format (der MIME-Type) dieser Datei nicht genau definiert ist, kann der Browser anhand des Inhalts den Dateityp selber bestimmen.

Im Falle unserer schadhaften .JPG-Datei würde der Browser nun feststellen (durch sogenanntes „MIME sniffing“), dass es sich um eine HTML-Datei handelt. Und die Datei dementsprechend als HTML-Datei behandeln und dadurch den Schadcode ausführen.

Mit dieser X-Content-Type-Options Einstellung „nosniff“ wird genau das verhindert: Der Browser darf nicht mehr selber versuchen, den Dateityp zu bestimmen (sprich, die angebliche .JPG-Datei mit dem Schadcode wird weiterhin nur als Bild-Datei behandelt, und eben nicht das versteckte HTML ausgeführt).

Kurz gesagt: Sinnvoll und deshalb einfach aktivieren:

Header set X-Content-Type-Options nosniff

#6: Content-Security-Policy

Das wäre zwar grundsätzlich eine sehr sinnvolle Option, muss aber für jede Website individuell konfiguriert werden.

Das Prinzip ist wie folgt: Für jeden Dateityp (z.B. JavaScript-Dateien) kann man definieren, von welchen (Drittanbieter-)Websites diese geladen werden dürfen.

Damit lässt sich im Falle einer Sicherheitslücke auf der Website äusserst effektiv verhindern, dass ein Angreifer von externen Websites Dateien mit Schadcode nachladen kann.

Das Problem ist:

In der heutigen Zeit werden auf den meisten Websites verschiedenste Dateien von Drittanbietern eingebunden. Sei es z.B. für Google Analytics oder beim Google Maps einbinden, oder beim Nutzen von einem CDN (Content Delivery Network), oder der Einbindung von YouTube, Facebook oder sonstiger Social Media Funktionen.

Es erfordert also ziemlich viel technisches Wissen, die korrekten Content-Security-Policy Regeln für alle genutzten Dienste zu erstellen.

Ausserdem müsste man bei jeder Änderung oder Erweiterung der Website wieder daran denken, die Content-Security-Policy entsprechend zu überarbeiten, was das ganze ziemlich fehleranfällig macht.

Deshalb gebe ich hier keine Empfehlung oder Code-Beispiel. Die allermeisten Leser dürfen die Content-Security-Policy ohne schlechtes Gewissen einfach ignorieren.

#7: Feature-Policy

Mit der Feature-Policy lassen sich einzelne Browser Funktionen wie z.B. Standortbestimmung, Webcam, Mikrofon oder Lautsprecher deaktivieren. Ausserdem lässt sich wie bei der Content-Security-Policy definieren, welche Funktionen nur von der eigenen oder eingebundenen Drittanbieter Websites verwendet werden darf.

Konkretes Beispiel: Man kann verhindern, dass der Standort der Besucher ausgelesen werden kann (z.B. von der eigenen Website und eingebundenen Facebook Funktionen), ausser bei der eingebundenen Google Maps Funktionen.

Auch diese Funktion ist zwar grundsätzlich sinnvoll, damit im Falle einer Sicherheitslücke auf der Website gewisse Funktionen wie eben z.B. die Webcam nicht ausgenutzt werden können.

Meiner Meinung nach ist es aber für die allermeisten Websites schlicht nicht praktikabel, da es zu viel technisches Verständnis erfordert und man sehr schnell ausversehen eine benötigte Funktion blockiert, ohne es zu merken.

Darum gebe ich auch hier keine Empfehlung oder Code-Beispiel. Die meisten Leser dürfen die Feature-Policy getrost ignorieren.

Praktische Umsetzung der 5 von 7 „einfachen“ HTTP Security Header

Hier jetzt also ein kompletter Beispiel-Code mit den 5 der 7 „einfachen“ und sinnvollen HTTP Security Header für die .htaccess Datei, die ich persönlich nutze:

<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=15768000" env=HTTPS
Header set X-XSS-Protection "1; mode=block"
Header set X-Content-Type-Options nosniff
Header set Referrer-Policy: no-referrer-when-downgrade
Header always append X-Frame-Options SAMEORIGIN
</IfModule>

Wichtig: Sollte es nach Hochladen der .htaccess Datei bei Ihrer Website zu einem Fehler kommen (typischerweise ein HTTP-Error 500 „Internal Server Error“), dann am besten den Code nochmals aus der .htaccess löschen und jede Zeile einzeln hinzufügen, um das genaue Problem einzugrenzen (und dann allenfalls eine andere Konfiguration auszuprobieren bzw. mit dem Hoster das Problem zu lösen).

Der „perfekte“ Security Header Score

Mit dieser von mir empfohlenen Konfiguration erhält man im SecurityHeaders.com Tool ein solides B:

HTTP Security Header Report

Was alles andere als Standard ist, wie z.B. das Beispiel von 20 Minuten zeigt:

HTTP Security Header Report

Wichtig: So ein Tool sagt nichts über die tatsächliche Sicherheit aus und ich empfehle definitiv nicht, einfach einem perfekten Score von irgendeinem Tool nachzurennen (worauf ich auch beim perfekten Google Page Speed Score hinweise).

Aber ich weiss, dass es eben doch viele Leser interessiert. Darum der Vollständigkeitshalber hier eine Anleitung, wie man den perfekten A+ Score erreicht:

Im Prinzip fügen wir für die Content-Security-Policy und die Feature-Policy eine Alibi-Regel ein, die keine wirklichen Sicherheitsvorteile bringt.

Bei der Content-Security-Policy können wir z.B. einfach sagen, dass alle Bilder (img-src) von jeder beliebigen Website (*) geladen werden dürfen (was sowieso Standard ist):

Header set Content-Security-Policy: "img-src *"

Und bei der Feature-Policy können wir z.B. definieren, dass die Vibrationsfunktion (vibrate) ausschliesslich von der eigenen Website (’self‘) genutzt werden darf, also nicht von eingebundenen Drittanbieter Funktionen wie z.B. Google Maps (was sowieso praktisch kein eingebundener Dienst wirklich benötigen sollte):

Header set Feature-Policy: "vibrate 'self';"

Hier also der komplette Code für die .htaccess Datei (hier habe ich auch noch den X-Frame-Options Header eingefügt):

<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=15768000" env=HTTPS
Header set X-XSS-Protection "1; mode=block"
Header set X-Content-Type-Options nosniff
Header set Referrer-Policy: no-referrer-when-downgrade
Header always append X-Frame-Options SAMEORIGIN
Header set Content-Security-Policy: "img-src *"
Header set Feature-Policy: "vibrate 'self';"
</IfModule>

Was uns schliesslich den perfekten A+ Score gibt:

HTTP Security Header Report

Wie gesagt, ich empfehle dieses Vorgehen nicht, aber das sollte zumindest auch als Anschauungsbeispiel sehr lehrreich sein 🙂

Michael Brütsch

Webdesigner & WordPress Experte: Ich kreiere WordPress Websites, die Google liebt (aka Suchmaschinenoptimierung / SEO).

Schreibe einen Kommentar

Benachrichtigung bei neuen Kommentaren (wenn Du eine E-Mail erhalten willst, sobald ich Dir geantwortet habe):