Nachdem ich in den zwei vorhergehenden Artikeln über HSTS, X-XSS-Protection und die Content-Security-Policy geschrieben habe, folgen nun die letzten kleineren HTTP Security Header. Dazu zählen unter anderem X-Content-Type-Options, X-Frame-Options, Feature-Policy und Referrer-Policy. Auf der Webseite von OWASP, dem Open Web Application Security Project, findet ihr auch eine gute Übersicht aller Header, Einstellungsmöglichkeiten und Best Practices. Wie in den letzten Artikeln beschreibe ich die Umsetzung der Header mit Apache via .htaccess-Datei.

X-Content-Type-Options

Der Header ist recht simpel, denn er hat nur 1 mögliche Option: „nosniff“. Mit dieser Eigenschaft verhindert der Header, dass der Browser einen übermittelten Content-Type MIME type ändert. Stattdessen muss der MIME-Type in jedem Fall befolgt werden, was MIME sniffing Attacken (auch „content sniffing“ genannt) verhindern kann. Bei diesem Angriffsszenario werden Dateien mit einem falschen MIME-Type an den Browser geschickt, welcher diese dann anders als vorgesehen interpretiert:

Header always set X-Content-Type-Options "nosniff"

X-Frame-Options

Die Angabe eines X-Frame-Options Header gibt vor, ob andere Seiten deine Seite einbinden können – als frame, iframe oder object. Verhindert werden dadurch vor allem Clickjacking Attacken. Damit steht dies im Gegensatz zur CSP, welche die Einbindung anderer Seiten in deine Seite behandelt. Drei Optionen stehen zur Auswahl: DENY, SAMEORIGIN und ALLOW-FROM [Domain].
Für WordPress ist es empfehlenswert, die Option SAMEORIGIN zu wählen, da es sonst Problemen geben wird, beispielsweise beim Update von Plugins.

Header always set X-Frame-Options "SAMEORIGIN"

Feature-Policy

Die Feature-Policy ermöglicht die Kontrolle vieler Browser-APIs und somit die Einschränkung der Angriffsquellen bei vielen Funktionen. Für jede Direktive (= API) können folgende Optionen gesetzt werden: * (alle Quellen erlaubt), self, none, [Domains]. Die Funktionalität ist also der CSP sehr ähnlich, aber mit Fokus auf Features. Auch wenn die Browserunterstützung noch recht mau ist, empfehle ich die Nutzung: Beschränkt die einzelnen APIs so, wie sie in eurer Seite benötigt werden und schafft damit etwas mehr Sicherheit. Eine report-Direktive ist wohl schon in Arbeit, aber noch nicht implementiert, ich hoffe das kommt bald noch.

Mehr Informationen zu den Direktiven auf dieser Google-Seite, der Github Seite (manche davon ausführlicher erklärt) und aktiv gezeigt auf dieser Demo-Seite. Das reicht als Hilfe für das Setup.

Ich aktiviere bei mir die Features autoplay, fullscreen und picture-in-picture für ’self‘, allesamt für embedded Videos brauchbar, der rest wird mit ’none‘ deaktiviert:

Header always set Feature-Policy "accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'self'; camera 'none'; encrypted-media 'none'; fullscreen 'self'; geolocation 'self'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; payment 'none'; picture-in-picture 'self'; speaker 'none'; usb 'none'; vr 'none'"

Ihr findet diese und weitere Einstellungen auch in den Webseiten-Einstellungen, die für jede Webseite angepasst werden können. Eure lokalen Settings stehen dabei noch vor den von der Seite vorgegebenen Featureeinstellungen:

mehr-website-sicherheit-mit-http-header-3-feature-policy-website-settings
Chrome’s Webseiten-Einstellungen für die Steuerung der Features

Referrer-Policy

Zuletzt noch die Referrer-Policy: Dieser Security Header steuert die Referrer-Information, die beim Aufruf eines Links auf eurer Seite mitgeschickt wird. Der Referrer ist dabei praktisch die Quelle der eingehenden Anfrage:

Grundsätzlich ist der Referrer eine nützliche Information, vor allem für Webseitenbetreiber und ihre Analysewerkzeuge wie Google Analytics. Sie erfahren, wie die Besucher auf die Webseite gekommen sind, von wo, eventuell mit welchen Suchbegriffen, und können ihre Seite mit diesen Informationen verbessern. Ich selber möchte hier also möglichst wenig restriktiv sein, aber dennoch die Sicherheit ein wenig erhöhen. Problematisch können Referrer-Informationen werden, wenn sie zu einer bösen oder unsicheren Seite weitergeleitet werden. Welche Möglichkeiten gibt es also?

Mögliche Optionen für die Referrer-Policy: no-referrer, no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url

Ich möchte jetzt hier nicht auf jeden Punkt eingehen, das wäre unnötig. Informiert euch gerne bei Mozilla (mitsamt Beispielen) oder in diesem Blog zu den Auswirkungen jeder Eigenschaft auf den Referrer.

Ich benutze aus oben genannten Gründen nur die Option ‚no-referrer-when-downgrade. Diese ist möglichst locker beim Aufruf beliebiger http://-Links und schickt den gesamten Referrer da mit. Ich habe in meinem Blog keine kritischen Informationen, die nicht weitergeschickt werden sollten. Allerdings wird die Weiterleitung meines Referrers auf unsichere http://-Seiten verhindert, das erhöht die Sicherheit ein wenig. Überdenkt eure Seite, eure Links und wie ihr mit dem Referrer selbst umgehen wollt.

Achtung WordPress-Nutzer: Ich glaube seit WordPress 4.7 werden target=“_blank“ Links automatisch mit der Eigenschaft rel=“noreferrer noopener“ erstellt. Das mag gute Hintergrundgedanken haben, wenngleich auch die Seite informiert, dass noopener den Angriff verhindert und noreferrer nur als compatibility backup benutzt wird.
Also unabhängig vom Referrer-Policy-Setting würden Links keinen Referrer mitsenden.
Es gibt mindestens 2 verschiedene Codes für die functions.php, mit der sich das deaktivieren lässt, beispielsweise siehe Link in diesem Absatz. Das Problem hierbei: Beide Codes funktionieren nicht mit dem neuen Gutenberg-Editor. Ich habe hier bisher keinen Weg gefunden, das automatische noreferrer zu entfernen und daher bleibt dieser Security Header bei mir mehr oder minder Placebo und für alle Fälle.

Fazit

Das waren nun also die wichtigsten sieben HTTP Security Header in drei Artikeln, das war doch eine ganze Menge neues Wissen. Ich hoffe, dass ihr etwas Hilfe finden und eure Webseitensicherheit ebenfalls verbessern konntet. Es gibt noch weitere Security Header, diese waren dann aber entweder kaum verbreitet, kaum unterstützt oder kritisch diskutiert und mir daher zu edge case für meine Artikel.

Im Großen und Ganzen bin ich zufrieden, auch wenn man sicher immer noch besser und sicherer sein kann, hier mein securityheaders.com Ergebnis:

mehr-website-sicherheit-mit-http-header-3-securityheader-summary-final
SecurityHeaders.com Ergebnis A nach den Header-Optimierungen

Dieser Beitrag ist eine Fortsetzung der kleinen Artikelserie zur Optimierung der HTTP-Header für mehr Sicherheit auf der Webseite und für alle Webseitenbesucher. In Teil 1 ging es um die zwei noch recht einfachen Header HSTS und X-XSS-Protection. Teil 2 wird nun den recht komplexen aber mächtigen Header Content-Security-Policy behandeln.
Es benötigt vom Webmaster schon einiges an Vorbereitung und Testing, um mit diesem Header nicht auch Schaden anzurichten, aber der Zugewinn an Schutz gegenüber Angriffen oder Code Injection ist bemerkenswert.

CSP für umfangreiche Datenherkunftseinschränkung

Der Content-Security-Policy Header überprüft die Art und Herkunft von Daten und Anfragen während des Ladens und kann darauf reagieren. So können beispielsweise bestimmte Datentypen wie Skripte oder Stylesheets, die von einer anderen URL als der gerade zu ladenden Webseite angefragt werden, geblockt werden. Damit wird verhindert, dass unerwünschte, fremde oder gefährliche Inhalte geladen und ausgeführt werden. Das ist für gewöhnlich das Ziel von XSS-Angriffen, welche über zahlreiche Tricks versuchen, schädliche Inhalte in vertrauenswürdige Seiten einzubinden.
Damit das jedoch so funktioniert, muss der Webmaster für alle oder einzelne Inhaltstypen die jeweiligen vertrauenswürdigen Quellen definieren. Hier wird es knifflig. Vergisst der Admin eine vertrauenswürdige Quelle, werden Inhalte von dort nicht mehr geladen und fehlen auf der Webseite. Das kann dazu führen, dass Schriftarten oder Bilder fehlen, Skripte und somit ganze Funktionen nicht mehr laufen und die Webseite sich in andere Seiten nicht mehr einbetten lässt. 
Die vertrauenswürdigen Ursprünge sind entweder bekannt oder müssen erarbeitet werden.

1. Informieren

Eine zu restriktiv gesetzte CSP kann die Webseite wie gesagt teilweise beschädigen. Ich empfehle daher die mehrstufige Vorgehensweise: Informieren, testen, optimieren und schlussendlich aktivieren.

Ein erster Blick lohnt beispielsweise bei MDN. Hier sehen wir, welche Direktiven und welche Werte möglich sind. Ich gehe später nochmal genauer auf die einzelnen Werte ein. Erst einmal solltet ihr euch einen groben Überblick holen. Nutzt für weitere Informationen neben diesem Artikel auch die Intros von html5rocks.com, SelfHTML, den Mehrstufen-Ansatz von dareboost.com und die dort verlinkten weiteren Artikel zu CSP-Basics und auch die vielen kleineren Webseiten und Blogger mit deren CSP-Empfehlungen.

2. Testen

Wir beginnen mit Tests, die keine Schäden anrichten können. Dazu nutzen wir das Report-Only Feature der CSP. Hierfür wird eine valide CSP über Content-Security-Policy-Report-Only gesetzt, angewendet aber nicht ausgeführt. Es werden Warnungen und Fehler ausgegeben, aber keine Anfragen tatsächlich blockiert. Gesetzt wird es wie gehabt in der .htaccess der Webseite:

<IfModule mod_headers.c> 
  Header always set Content-Security-Policy-Report-Only: "default-src 'self'; img-src 'self' https://secure.gravatar.com https://s.w.org https://wordpress.org https://ps.w.org data:; font-src 'self' fonts.gstatic.com data:; object-src 'none'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; connect-src 'self'; child-src 'self'; report-uri https://report-uri.de/report.php;"
</IfModule>

Der Inhalt dieser CSP ist erst einmal nur kopiert von kittpress.com und angepasst an das Report-Only Feature via .htaccess. Von hier arbeite ich mich dann weiter.

Die CSP wird nun theoretisch angewendet, aber nicht endgültig ausgeführt. Nun könnt ihr anhand der Browser-eigenen Dev-Tools und der Reports die Problemstellen identifizieren.
Wie ihr eine Report-Schnittstelle einrichtet, die beispielsweise Reports in eine Logdatei schreibt, habe ich im ersten Teil dieser Artikelserie erklärt. Ihr könnt auch genau dieselbe Reportschnittstelle hierfür nutzen, das funktioniert einwandfrei. Alternativ könnt ihr auch externe Report Services wie diesen als Ziel für eure Reports wählen.
Gegenüber euren Browsertools haben die Reports den Vorteil, dass jede CSP-Verletzung jedes Website-Besuchers an euch gemeldet wird – ohne, dass ihr dafür dann noch etwas tun müsst. Außerdem habt ihr alle Meldungen dann in einer großen und zentralen Server-Log (ggf. auch per Mail) und müsst nicht selbst rumsurfen und die Devtools abkopieren. Es geht ansonsten aber auch ohne report-uri.

3.1 Optimieren

Bei meinem ersten Test landeten weit über 100 Reports innerhalb von 1 Minute in der Report-Log – das reicht für eine erste Optimierung. Also habe ich die CSP erst einmal wieder deaktiviert/auskommentiert und die ersten Ausnahmen erstellt. Dazu habe ich mir jeden Report einzeln angesehen, wenn nötig eine Ausnahme erstellt, alle Logeinträge dieses spezifischen Problems entfernt, nächten Report angesehen. So lange, bis die Report-Log wieder leer war.
Anschließend die neue CSP wieder einkommentieren und wieder dreistellige Reports sammeln.
Diesmal dauert es länger und es kommen kleinere oder speziellere Probleme zum Vorschein: Von externen Seiten eingebundene Bilder oder Medien, alte http:// embeds von z.B. alten Google Maps Projekten, extern genutzte Services, Einbindungen von Inhalten noch über meine alte Domain hannes-schurig.de, externe Inhalte in Kommentaren usw.
Ich habe hier durchaus 2-3 Stunden verbracht, alte Blogartikel zu bearbeiten, Links zu korrigieren, meine alte Domain überall zu ersetzen, Kommentare zu korrigieren und mehr.
Nach 4-5 Iterationen über 3 Tage ist meine CSP nun ganz gut und die letzten 24 Stunden ergaben nur noch Reports, die geblockt werden können. Es verbleiben Logs von geblockten Domains wie countmake.cool, loadsource.org und eluxer.net – fragt mich nicht, was das ist. Manche Blocks kommen durch data, blob oder chrome-extension, ich denke das ist auch okay zu ignorieren.

Mit dieser Endfassung bin ich nun also ganz zufrieden und werde diese nun endgültig aktivieren:

<IfModule mod_headers.c> 
  Header always set Content-Security-Policy-Report-Only: "default-src 'self'; \
script-src 'self' 'unsafe-inline' 'unsafe-eval' www.google-analytics.com https://*.googleapis.com https://www.google.com https://www.gstatic.com https://*.vgwort.de https://*.it-stack.de; \
img-src 'self' https://*.gravatar.com https://*.w.org https://*.wordpress.org www.google-analytics.com https://*.vgwort.de https://www.gstatic.com https://*.it-stack.de data:; \
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://*.it-stack.de https:; \
font-src 'self' data: https:; object-src 'none'; \
child-src 'self' https://www.google.com https://*.youtube.com https://*.it-stack.de https:; \
frame-src 'self' https://www.google.com https://*.youtube.com https://*.it-stack.de https:; \
worker-src 'self' https://www.google.com https://*.youtube.com https://*.it-stack.de https; \
connect-src 'self' wss://it-stack.de www.google-analytics.com https://*.vgwort.de; \
report-uri https://report.tld/report.php"
</IfModule>

Die Backslashes am Ende der Zeilen ermöglichen Zeilenumbrüche in .htaccess Dateien zur besseren Lesbarkeit.

3.2 Verstehen

Ein paar kleinere Hinweise oder Ergänzungen dazu:

default-src ’self‘ wird angewendet, wenn eine andere Direktive, die für eine Anfrage gebraucht wird, gar nicht vergeben wurde. Ist eine Direktive gesetzt, wird default-src komplett überschrieben, dortige Werte werden nicht vererbt. Beispiel: img-src abc.com würde das ’self‘ von default-src nicht vererben, ’self‘ sollte daher fast immer mit angegeben sein.

Mir ist klar, dass unsafe-inline/-eval die größte Schwachstelle der CSP sind, allerdings auch das größte Problem bei WordPress Blogs mit etlichen Plugins, Google Analytics und mehr. Der Aufwand, diese zwei Attribute zu entfernen, kann sehr aufwändig und langwierig werden. Ich betrachte diese CSP jetzt vorerst als (wenn auch schon fortgeschrittenes) MVP – minimum viable product 😉

CSS-Stylesheets wirken eher harmlos, enthalten schließlich nur kosmetische Informationen, wieso einschränken? Es ist nicht zu unterschätzen, wieviel Spionage auch durch CSS-Angriffe wie z.B. „CSS Exfil“ möglich ist.

Ebenso Fonts, ist das nicht etwas too much? Nein, auch Fonts können zu Keyloggern umfunktioniert und müssen daher ebenso gut eingeschränkt werden.

child-src ist noch CSP Version 2 und wird angeblich (laut dieses Validators) in Version 3 durch frame-src und worker-src ersetzt. Ich habe also vorsichtshalber einfach mal alle drei Direktiven so gesetzt. Parallel am besten immer noch mit Google’s Validator testen.

4. Aktivieren

Nachdem die CSP nun definiert und einige Stunden ohne neue benötigte Regel im Testbetrieb lief, kann sie nun aktiviert werden. Dazu einfach nur Content-Security-Policy-Report-Only in Content-Security-Policy umschreiben und fertig. Beobachtet selber noch einmal die Webseite, auch das Admin Backend und wenn alles funktioniert, ist es geschafft!

Ich werde vorerst die Log noch im Blick behalten, bin aber erstmal froh, auch diesen Punkt soweit erledigt zu haben:

Es wird langsam… 3 Security Header gesetzt, CSP ist neu

mehr-website-sicherheit-mit-http-header-hsts-xss-protection-banner

Zum Start dieser kleinen Serie, inspiriert durch einen Sicherheitsreport meines Blogs von enginsight.com (dazu mehr im November), erst einmal die Grundlagen der HTTP-Header:

Was sind HTTP-Header und wofür brauche ich sie?

HTTP-Header, oder in diesem Artikel vor allem die HTTP-Header-Respond-Felder, sind ein Teil der Antwort eines Webservers an den anfragenden Client (mehr dazu). Sie enthalten Anweisungen, Informationen und Einschränkungen der Verbindung zwischen Browser und Server, aufgebaut als eine Vielzahl an Schlüssel-Wert-Paaren.
Der Betreiber einer Webseite oder eines Webservers kann diese Antwortfelder teilweise konfigurieren und damit die Sicherheit der Webseite und des Verbindungsaufbaus erhöhen. Die Felder, die speziell für mehr Sicherheit entwickelt wurden, werden auch kurz HTTP-Security-Header genannt.

Die Anpassung der Header kann unterschiedlich erfolgen und ist vom Webserver oder der Webhosting Umgebung abhängig. Webserver bieten für HTTP gewöhnlich Konfigurationsdateien an, teilweise gibt es diesen Zugriff auch in root-Webhosting-Lösungen. Für „normales“ Webhosting geht das größtenteils auch über eine .htaccess in der obersten Ebene. Das könnte im Falle meines Webhosters All-Inklusive beispielsweise sein:
/www/htdocs/w00bxxxx/.htaccess

Mögliche Probleme mit .htaccess bei Shared Webhosting

Achtung: Eventuell werden Header Anpassungen von eurem Hoster geblockt/entfernt. Das liegt dann an der Art und Weise der Webserver-Konfiguration.
Sidestory: Bei meinem Hoster All-Inklusive, dessen Shared Hosting Server größtenteils PHP über FPM/FastCGI realisieren, ist das beispielsweise der Fall. Hier müssten die Einstellungen direkt im VHost gesetzt werden, das kann nur der Hoster selbst. Freundlicherweise hat mich All-Inkl nach einer Nachfrage auf eine moderne Serverfarm umgezogen, wo ich mittels .htaccess auch Header setzen kann.
Sollte das für euch nicht möglich sein, funktioniert für WordPress auch der Workaround über die functions.php, den ihr auf dieser Seite ganz unten im letzten Absatz findet. 
Teilweise kann es auch sein, dass die Einträge durch Einstellungen im Admin-Backend überschrieben werden. So kann es sein, dass HSTS, „Enforce SSL“ und ähnliche Domain-basierte Eigenschaften in der Domänenverwaltung angepasst werden und die .htaccess Angaben überschreiben.

Hier die Analyse meines Blogs von securityheaders.com vor der Optimierung der Security Header:

mehr-website-sicherheit-mit-http-header-hsts-xss-protection-header-analyse-davor
Security Header Analyse vorher mit der Endwertung D, nicht so vorteilhaft…

Kein sehr gutes Bild. Wird Zeit, daran zu arbeiten! Wir beginnen mit zwei recht unkomplizierten Security Feldern, HSTS und XSS-Protection. Sie bieten einen guten Einstieg in das Themengebiet und benötigen jeweils nur 1 Zeile in der .htaccess. Aber nun in die Details:

HTTP Strict Transport Security – SSL & HTTPS, bis dass der Tod uns scheidet

HSTS (HTTP Strict Transport Security) sollte ausschließlich aber unbedingt dann konfiguriert werden, wenn die Webseite SSL verschlüsselt (über https) erreichbar ist und nicht mehr über unverschlüsseltes HTTP erreichbar sein soll. HSTS gibt vor, dass und für welchen Zeitraum in der Zukunft alle Anfragen über SSL vom Client zum Server geschickt werden müssen.

<IfModule mod_headers.c>
  # Die einfache HSTS Variante, halbes Jahr Zeitfenster
  # Header always set Strict-Transport-Security "max-age=15778463"
  # oder noch sicherer mit Subdomains, preload und allen Subdomains
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</IfModule>

Zwei Werte sind hier wichtig: max-age und der optionale Parameter includeSubDomains. max-age ist die Zeitangabe in Sekunden, wie lange der Zugriff in Zukunft für diesen gerade aufrufenden Client ausschließlich über SSL erfolgen muss. Der Wert 31536000 steht demnach für 1 Jahr. Ist die Webseite innerhalb dieser Zeit nicht über https erreichbar, weil beispielsweise das Zertifikat abgelaufen ist, kann sie nicht mehr geöffnet werden. Browser geben dann diese Art von Fehlermeldung und für den Nutzer ist hier Endstation. Das kann jetzt für den Nutzer doof sein, sorgt aber für ein hohes Sicherheitsminimum, das nicht unterschritten werden darf. Eigentlich ein Plus.

Ein Blick in die weiteren Eigenschaften von HSTS lohnt sich

Die zusätzliche Angabe includeSubDomains erweitert dieses Verfahren auf alle Subdomains, ein Wildcard-Zertifikat ist hier also von Nöten. 
Zu guter Letzt gibt es noch die preload-Eigenschaft, die noch nicht Teil des offiziellen Standards ist. Es ist die Crème de la Crème der HSTS-Absicherung und implementiert den HSTS-Schutz für eure Domain explizit und direkt in alle modernen Browser (akt: Chr, FF, Opr, Saf, IE11, Edg). Dafür muss die Seite jedoch HSTS ordentlich eingebunden haben und auf dieser Seite registriert werden. Dieser Artikel beschreibt sehr ausführlich und einfach dieses Attribut und all seine Details.
Prüft die HSTS-Eigenschaften eurer Seite beispielsweise hier. Mehr Informationen zu HSTS auch hier. Einen ausführlichen Check eurer SSL-Servereigenschaften könnt ihr hier initiieren – das dauert 2, 3 Minuten, ist aber sehr ausführlich und informativ.

X-XSS-Protection – steckt mehr drin als gedacht

Als nächste Eigenschaft schauen wir auf das Feld X-XSS-Protection. Dieses steuert Browser-Features, welche XSS-Attacken erkennen und verhindern. Diese Mechanismen sind normalerweise aktiviert, können aber von Servern oder vom Nutzer deaktiviert werden; X-XSS-Protection erzwingt die Nutzung dann entsprechend der Angabe. Oft lese ich, dass der Header nur von IE und Chrome, teilweise auch von Safari ausgewertet wird. Laut MDN wird der Header jedoch von allen Browsern bis auf Firefox unterstützt. Folgende Umsetzung via .htaccess:

<IfModule mod_headers.c> 
  # Schutz aktivieren und Rendern verhindern bei einem Angriff
  # Header always set X-XSS-Protection "1; mode=block" 
  # oder noch besser: Seite aufräumen, rendern und Angriff melden:
  Header always set X-XSS-Protection "1; report=http://reportingserver.com/reporting_URI.php
</IfModule>

Relativ einfach: Der erste Wert 1 erzwingt-aktiviert den Schutz, mode=block stoppt das Rendering der Seite und blockiert sie komplett. Ohne mode=block wird die Anfrage gereinigt und dann ausgeführt. Soweit so einfach.

XSS-Protection Reporting – Mitlesen der Angriffe

Nun kommt jedoch noch eine spannendere Anweisung, die leider auf kaum einer Infoseite beschrieben wird; vermutlich, weil es etwas mehr Text brauch. Denn die report-Anweisung ermöglicht die Angabe einer Reporting-URI, an die ein Bericht des Angriffs geschickt wird. Das dortige Skript kann nun beispielsweise loggen, benachrichtigen oder beliebig anders reagieren. Das finde ich besonders wert- und sinnvoll, daher hier noch der Aufbau:
Beginnen wir mit dem beispielhaften Aufbau eines XSS-Protection Report Requests, welcher mittels POST an die URI geschickt wird:

POST http://test.local/foo HTTP/1.1
Host: test.local
Connection: keep-alive
Content-Length: 116
Pragma: no-cache
Cache-Control: no-cache
Origin: http://test.local
X-FirePHP-Version: 0.0.6
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.65 Safari/537.36
Content-Type: application/json
Accept: */*
DNT: 1
Referer: http://test.local/test.php?foo=%3Cscript%3Ealert(1);%3C/script%3E
Accept-Encoding: gzip, deflate
Accept-Language: cs,en-US;q=0.8,en;q=0.6

{"xss-report":{"request-url":"http://test.local/test.php?foo=%3Cscript%3Ealert(1);%3C/script%3E","request-body":""}}

Nun wird der Request gegen ein PHP-Skript geschickt und dort empfangen, in eine Datei geloggt und per Mail an den Admin geschickt. Dazu habe ich diesen MDN-Code etwas erweitert: Es gibt jetzt mehr Mailing-Optionen und die Möglichkeit, eine E-Mail bei jedem Angriff zu senden, statt nur beim ersten:

<?php
// Start configure
$log_file = dirname(__FILE__) . '/xss-report.log';
$log_file_size_limit = 10000000; // in bytes = 10MB - once exceeded no further entries are added
$email_every_attack = true;
$email_sender = 'phpmailer@mysite.de';
$email_recipient = 'admin@mysite.de';
$email_subject = 'XSS Violation';
$email_charset = 'utf-8';
// End configuration

$current_domain = preg_replace('/www\./i', '', $_SERVER['SERVER_NAME']);
$email_subject = $email_subject . ' on ' . $current_domain;
http_response_code(204); // HTTP 204 No Content
$json_data = file_get_contents('php://input');

// We pretty print the JSON before adding it to the log file
if ($json_data = json_decode($json_data)) {
  $json_data = json_encode($json_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
  if ($email_every_attack) {
    // Send an email
    $message = "XSS violation on " . $current_domain . ":\n\n" .
      $json_data . "\n\n" .
      "Logfile:" . $log_file;
    $headers =  "From: ".$email_sender."\r\n".
                "Content-Type: text/plain;charset=".$email_charset;
    mail($email_recipient, $email_subject, $message, $headers);
  } else if (filesize($log_file) > $log_file_size_limit) {
    exit(0);
  }
  file_put_contents($log_file, $json_data."\n", FILE_APPEND | LOCK_EX);
}
?>

Am besten testet ihr die Reporting-Funktion vorher, beispielsweise über einen online API-Tester. Baut euch einfach den Request zusammen und schickt ihn an eure Report-URI. Das funktioniert gut und dient mir nun als Informationsquelle, welche XSS-Angriffsversuche mit exakt welchen Anfragen gegen meine Seite gefahren werden. Hier nochmal das Setup visuell:

mehr-website-sicherheit-mit-http-header-hsts-xss-protection-report-setup_thumb
XSS-Protection Reporting Setup mit Logging und Mailing

Es sei erwähnt, dass die X-XSS-Protection durch die neuere und komplexere Content Security Policy (CSP) ersetzt wird. Das schauen wir uns im nächsten Artikel genauer an. Solange dieses Feld aber noch nicht komplett von allen Browsern unterstützt wird, empfiehlt es sich weiterhin, XSS-Protection zu verbauen (zumal es so einfach ist).

Abschluss der ersten Optimierung

Die ersten zwei Security Header sind damit optimiert, ein erster Schritt:

Das Jahr 2019 hat ja „gut“ angefangen: Anfang Januar ein großer Leak im Bereich Politik und öffentliche Personen sowie Ende Januar ein weiterer Leak mit 2,7 Milliarden Zeilen an Daten. Obwohl Letzterer wohl „nur“ rund 770 Millionen valide Datensätze enthielt, war es einer der größten Accountdaten-Leaks der letzten Jahre. 2018 war bereits mit Leaks und den großen CPU-Lücken Meltdown und Spectre recht kritisch.
Das zeigt doch, dass es selten wichtiger war als heutzutage, seine digitalen Accounts und Netzwerke sowie Technik und Geräte zu schützen. Aus diesem Grund habe ich mal ein paar Tipps und Links zusammengetragen, die zu mehr Sicherheit verhelfen, wenn ordentlich umgesetzt:

  1. Prüft auf den bekanntesten Internetseiten, ob eure Daten bereits von Leaks/Hacks betroffen sind. Schaut mal in meinen Leak-Check-Artikel, den habe ich auch nochmal aktualisiert. Die wichtigsten Anlaufstellen bleiben der Identity Leak Checker meines aktuellen Arbeitgebers 😉 (HPI) und HaveIBeenPwned.com (ins Deutsche übersetzte Infos dieser Seite gibt es auf dieser Seite).
  2. Setzt sichere und lange Passwörter und am besten unterschiedliche Passwörter für jeden eurer Logins/Seiten/Dienste! Dazu gehören Passwörter mit mehr als 12, besser mehr als 14 Zeichen aus allen Zeichengruppen (Groß- und Kleinbuchstaben, Sonderzeichen, Zahlen).
    Somit wäre ein öffentliches Passwort nur riskant für diese 1 Seite, das Passwort wäre nicht weiterzuverwenden. Ich verwende schon ewig unterschiedliche Passwörter mit mehr als 16 Zeichen für jeden meiner Logins. Da sich das auf Dauer und bei der Anzahl (ich habe über 300 Zugangsdaten…) niemand merken kann, empfehle ich hier einen Passwortmanager. Ich selber nutze KeePass, da dieser kostenlos und gut erweiterbar ist, aber es gibt etliche Alternativen, die nur ein paar Euro kosten. Zusätzlich können im Passwortmanager auch wichtige und kritische Infos, beispielsweise Kreditkarteninformationen, hinterlegt werden. Das Masterpasswort für den Safe sollte bezüglich Länge und Komplexität euer Meisterwerk werden 😉 Die meisten Programme bieten auch an, den Safe mit mehreren Sicherheitsfeatures zu schützen. Neben dem Masterpasswort kann somit ein Key File oder USB Dongle erforderlich sein, um den Safe zu öffnen. Prüft hier mal, was eure Software kann und erfordert im besten Fall mindestens zwei Zugangsmethoden.
  3. Aktiviert alle möglichen Sicherheitsfeatures eurer Accounts: Je nach Anbieter werden euch meistens verschiedenste Features zur Verfügung gestellt, welche den Zugang zum Account im Normalfall oder im Notfall (Passwort vergessen, E-Mail-Adresse nicht mehr verfügbar) gewährleisten sollen. Aktiviert diese Features und füllt sie mit euren Daten.
    1. 2-Faktor-Authentifizierung ist sowieso ein Muss für alle wirklich wichtigen Dienste, alles was mit Geld und großen Mengen eurer persönlichen Informationen zu tun hat.
    2. E-Mail-Benachrichtigungen aktivieren bei bestimmten Events, beispielsweise wenn Geld abgehoben, das Passwort geändert wird oder fehlerhafte Logins erfolgten.
    3. Konto-/Passwort-Wiederherstellungsfunktionen aktivieren; hier müssen meist weitere Infos wie Handynummern bereitgestellt werden oder Sicherheitsfragen festlegen, um im Notfall alternativen Zugriff zu bekommen. Vorsicht bei den Sicherheitsfragen: Die Antworten darauf solltet nur ihr selbst wissen und nicht irgendwo im Netz über euch herausfindbar sein.
  4. Wenn ihr Google und dessen Dienste so intensiv nutzt wie ich, empfehle ich vor allem hier alle Sicherheits- und Datenschutzeinstellungen durchzugehen. Ihr könnt hier wirklich sehr viel anpassen. Lest dazu meinen Artikel, dort liste ich alle Informationen kurz und knapp auf.
  5. Schützt alle Geräte und Hardware ebenso gut wie die digitalen Accounts: Gute PINs und Passwörter, Backups (vielleicht in einer sicheren deutschen Cloud?), Geräteverschlüsselung, zusätzlich Fingerabdruck/Gesichtserkennung, Anti-Diebstahl-Schutz eurer Smartphones sowie allgemein gute Sicherheitseinstellungen, Sicherheit und Backups einzelner Apps prüfen. Ein paar Android Basics noch, die können irgendwann mal helfen.
  6. Als Webseitenbetreiber habt ihr zudem zusätzliche Verantwortung mit euren Seiten und solltet auch dort die Sicherheit eurer Besucher gewährleisten und optimieren. Dazu gehört ein gut abgesichertes Backend/Logins, Optimierungen ausgehender Mails, optimierte HTTP-Header, regelmäßige Backups, verschlüsselte Passwörter in der DB, unterschiedliche Passwörter für Backend/DB/FTP/SSH oder Zugriff nur per SSH Key statt Passwort.
  7. Schützt eure Betriebssysteme und Software und haltet diese auf dem neuesten Stand. Die aktuellste Version von OS, Software und App schützt euch bestmöglich gegen aktuell bekannte Schwachstellen dieser. Zieht euch die Updates im besten Falle immer von den offiziellsten Quellen – Software von der Webseite der Software/des Betreibers, Apps aus dem offiziellen App-Store. Vermeidet Software-Downloader oder Portale wie CHIP, Netzwelt oder freeware.de – dort wird gerne ungewollter Kram untergejubelt. Installiert zusätzlich Sicherheitssoftware gegen Viren und ggf. gegen Werbung, wenn ihr euch unsicher fühlt oder bestmöglich vorsorgen wollt.
  8. Spam und Phishing ist zwar ein alter Hut aber noch immer nicht ausgestorben. Ganz im Gegenteil erhalten wir mittlerweile zwar wenig aber dafür teilweise recht gute unerwünschte E-Mails. Achtet also auch heute immernoch sehr kritisch und mit der nötigen Vorsicht bei Mails auf ihre Echtheit. In meinem vorherigen Artikel habe ich über die Standard-Tipps bei der Erkennung von Spam und Schadmails geschrieben. Wer sich bei dem Thema noch unsicher fühlt, sollte mal reinlesen.
  9. Nutzt Verschlüsselung wo immer möglich. Verschlüsselte Messenger wie Threema oder Signal (und an sich auch Whatsapp) übermitteln die Kommunikations mit Ende-zu-Ende-Verschlüsselung. Mails lassen sich beispielsweise mit PGP verschlüsseln und manche Anbieter wie ProtonMail haben das direkt schon unsichtbar integriert. Verschlüsselte Daten-Safes beispielsweise mit VeraCrypt sind sichere Ablageorte für kritische Dokumente und Daten. Sichere Cloudanbieter mit Verschlüsselungs-/Passwortfeature sind ebenfalls praktisch.
  10. Auch der physische Schutz der Hardware selbst darf nicht vernachlässigt werden. Letztlich ist ein Ausfall der Hardware im schlimmsten Falle auch mit Datenverlust verbunden, was zumindest emotional fast schon ein größerer Schaden sein kann als die Arten von digitalem Datendiebstahl der oberen Punkte. Sorgt deswegen für eine fachgerechte Installation aller Hardware in eurem Computer, schließt das Gehäuse ab wenn dieses in öffentlich zugänglichen Bereichen steht (zusätzlich ist dann ein BIOS-seitiges IDS sinnvoll), schützt schützenswerte Komponenten beispielsweise mit einem Schutzlack von RS Components und reinigt das ganze System regelmäßig beispielsweise durch Aussaugen, trocken Auswischen und Reinigen der Lüfter.

Ich denke das reicht erstmal als Grundlage, da geht sicher noch einiges mehr. Schickt mir gerne weitere Hinweise und Punkte, die ich hier dann noch ergänzen werde. Bis dahin: Stay safe! 🙂

Über

Meinen Blog gibt es nun schon seit fast 10 Jahren, verrückte Sache. Und obwohl ich grob über 300 Tutorials und How-To’s geschrieben habe, ist es wie so oft: Der Schuster hat gerne mal die schlechtesten Leisten. Wartung und Pflege des eigenen Systems geraten bei viel Stress und wenig freier Zeit in den Hintergrund. So kommt es, dass mich die Firma Enginsight letztens kontaktiert hat. Der Inhalt war ein weniger positiv – man übergab mir einen Sicherheitsbericht meines Blogs. Dieser enthielt Bewertungen in mehreren Kategorien und leider nicht nur gute, dazu später mehr. Das war der Anlass, dass ich mich mit der Sicherheits-Suite von Enginsight und der Sicherheit meines Blogs detaillierter auseinandergesetzt habe.

Erster Eindruck

Die Suite von Enginsight möchte mit ihren Tools die Sicherheit und Verfügbarkeit von IT-Netzwerken erhöhen und den Aufwand der Wartung und Überwachung verringern. Das Netzwerk kann hier beliebig verschieden und groß sein – von 1 Webseite, einem PC oder Server bis hin zu einem aus mehreren Nodes und Netzwerkkomponenten bestehenden Netzwerk.

Dank des 14-tägigen Probeaccounts lässt sich die Suite auch direkt selbst ausprobieren. Nach dem Login lande ich auf einem sehr übersichtlichen Dashboard, in dem mir meine eingerichteten Assets (in diesem Moment natürlich noch keine) angezeigt werden. Über eine Menüleiste habe ich schnellen Zugriff auf die wichtigsten Funktionen: Umgebungen, Hosts, Endpunkte, Alarme, Einstellungen, Suche, mein Profil sowie einigen weiteren Kleinigkeiten.

webseiten-netzwerke-analysieren-kontrollieren-enginsight-suite-dashboard
Übersichtliches Enginsight Dashboard mit ersten angelegten Assets

Detaillierte Analysen

Ich habe hier direkt meinen Blog als einen Endpunkt angelegt. Endpunkte sind Webseiten oder Webapplikationen, für die verschiedene Funktionen zur Verfügung gestellt werden: Webseite (Verfügbarkeitstests aus EU/USA), SSL/TLS, Web Thread Intelligence, Portscan, HTTP-Headers und Redirects. Die Funktionen können flexibel hinzugefügt werden. Anschließend starten direkt die ausgewählten Untersuchungen auf das eingegebene Ziel und nur wenige Sekunden später erhalte ich eine ausführliche Analyse meiner Seite:

Schnell ist klar: Hier muss was gemacht werden! Ich gehe mal kurz die Features durch und was jeweils untersucht wird:

  • Webseite: Stündliche Verfügbarkeitstests von Servern aus Frankfurt (EU) oder East-Virginia (USA), Analyse der Verbindungszeiten (wieviel Millisekunden Lookup, Connect, Transfer usw.)
  • HTTP-Headers: Analyse der Antwort-Header-Eigenschaften und speziell der Security-Header. Dazu mehr im Kapitel weiter unten
  • SSL/TLS: Untersuchung des verwendeten SSL-Zertifikats, der unterstützten Protokolle und Chiffren sowie möglicher Sicherheitslücken bzgl. SSL
  • Redirects: Weiterleitungen der Domain
  • Web Threat Intelligence: Prüfung von Sicherheitslücken beim Server, benutzten Anwendungen, der Webseite, benutzter Frameworks und Errechnung eines Scores
  • Portscan: Offene Ports und deren Service, ggf. Informationen zu eingesetzter Software und Version hinter einem Port

Bei der dauerhaften Verwendung von externen Dienstleistern, vor allem wenn (personenbezogene) Daten der eigenen Plattform dort verarbeitet werden, müsst ihr darauf achten, das Verzeichnis von Verarbeitungstätigkeiten zu ergänzen. Ansonsten wäre das im worst-case ein Datenschutzverstoß.

Ein Bericht hat mir dabei besonders wenig gefallen: Die Bewertung F bei den HTTP-Header. Also habe ich hier mal einen detaillierteren Blick geworfen:

Crashkurs HTTP-Headers

HTTP-Header sind Anweisungen, die vom Server- oder Webseitenbetreiber konfiguriert werden, um die Sicherheit des Webangebots sowie der Besucher zu erhöhen
Die Anweisungen können, je nach Hosting Setup, recht einfach über die .htaccess (empfohlen beim Shared Webhosting) gesetzt werden.
Im folgenden nenne ich zwei beispielhafte Security-Header, es gibt jedoch noch mehr:

HTTP Strict Transport Security (HSTS)

HSTS gibt vor, dass und für welchen Zeitraum in der Zukunft alle Anfragen über HTTPS/SSL vom Client zum Server geschickt werden müssen. Anfragen über HTTP werden innerhalb dieses Zeitfensters dann komplett geblockt. Eine Beispielkonfiguration wäre:

<IfModule mod_headers.c>
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</IfModule>

Anzupassen: max-age als Zeitangabe in Sekunden, wie lange der Zugriff in Zukunft für diesen gerade aufrufenden Client ausschließlich über SSL erfolgen muss. Der Wert 31536000 steht demnach für 1 Jahr. includeSubDomains erweitert dieses Verfahren auf alle Subdomains. Weitere Informationen und Details zu HSTS und die preload-Eigenschaft in meinem separaten Artikel zum Thema HSTS und XSS-Protection hier.

Content-Security-Policy (CSP)

Der Content-Security-Policy Header überprüft die Art und Herkunft von Daten und Anfragen während des Ladens und kann darauf reagieren. Damit wird verhindert, dass unerwünschte, fremde oder gefährliche Inhalte geladen und ausgeführt werden. Das ist für gewöhnlich das Ziel von XSS-Angriffen und Code-Injections, schädliche Inhalte in vertrauenswürdige Seiten einzubinden.

Die Kontrolle der Inhalte wird hierbei in unterschiedliche Kategorien (auch Direktiven genannt) aufgeteilt und jeweils können erlaubte Datenquellen definiert werden. Beispielsweise gibt die Direktive script-src an, von welchen Domains und Quellen Skripte in die geschützte Seite eingebunden werden dürfen. Ein CSP-Beispiel:

Header always set Content-Security-Policy: "default-src 'self'; img-src 'self' https://secure.gravatar.com https://wordpress.org data:; script-src 'self'; font-src 'self' fonts.gstatic.com; report-uri https://report-uri.de/report.php"

Diese CSP definiert erlaubte Datenquellen für die Direktiven default-src, img-src, script-srcfont-src und definiert einen Bericht-Endpunkt mit report-uri. Die Angabe ’self‘ erlaubt Daten von der eigenen Domain, in der die CSP benutzt wird. Zusätzlich wurden für Bilder die Domains von gravatar.com und wordpress.org sowie die Einbindung von data-uri Bildern als Ausnahmen definiert. Ebenso das Laden von Schriften vom Google Repository. Wenn ein Angreifer nun versucht, beispielsweise über einen Kommentar ein Skript von seiner Angreiferdomain einzubetten, würde die CSP dies blocken, da nur die eigene Domain Skripte einbinden darf.

Mehr zum Aufbau und Einrichtung des CSP Header in meinem Artikel zu diesem Thema hier.

Sicherheit von Hosts auch mit Künstlicher Intelligenz überwachen

Zurück zur Enginsight-Suite, denn hier gibt es noch viel mehr zu entdecken! Aus Gründen der Komplexität reiße ich die folgenden Features nur grob an.

Wie eingangs erwähnt, lassen sich auch Computer und Server in das System einfügen und durchleuchten. Dafür wird ein Client auf den Geräten eingerichtet und schon werden etliche Systemkomponenten untersucht: Auslastung von CPU, RAM, SWAP, integrierte Partitionen, Netzwerkschnittstellen, installierte Software und Updates sowie laufende Prozesse. Daran erkennt Enginsight dann mögliche Sicherheitsrisiken und gibt Handlungsempfehlungen.

Außerdem wacht eine auf Neuralen Netzwerken basierende Künstliche Intelligenz über die erfassten Daten. Auf Wunsch erkennt diese beispielsweise wenn personenbezogene Daten das Netzwerk verlassen oder bestimmte Metriken wie CPU oder RAM ihre Normalwerte verlassen. Basierend auf den gelernten Daten erkennt die KI Anomalien und alarmiert den Admin. Dieser kann den Vorfall dann einstufen und die KI lernt für zukünftig Entscheidung aus diesem Handeln. Somit wird die KI immer intelligenter und der Admin hat weniger Verwaltungsaufwand.

Im Peacemaker werden die Systemupdates aller angelegten Hosts in einer Übersicht angezeigt und können direkt verwaltet werden. So lassen sich beispielsweise unter Linux Updates direkt aus Enginsight heraus installieren.

Unter dem Menüpunkt Umgebung versteckt sich ein Visualisierungstool, mit dem die angelegten Assets miteinander in Verbindung gebracht werden können. Außerdem lassen sich hier auch Notizen oder ganze Dokumentationen für jedes Asset hinzufügen. So fehlt nie der Überblick bei komplexen Infrastrukturen.

Automatisierung über Alarme und Plugins

Zwei weitere Funktionen lassen sich gut kombinieren, um eine Automatisierung von Maßnahmen im Problemfall zu realisieren: 
Alarme können erstellt werden, um regelmäßige Überprüfungen durchzuführen und im Problemfall Maßnahmen zu ergreifen. Mögliche Überwachungen bei einem Endpunkt: Response Time, Tage bis Zertifikatsablauf, Webseite nicht erreichebar, Neue Sicherheitslücke, Datenschutzverstoß. Für Hosts gibt es noch mehr, hier nur ein paar: Temperatur, neue oder entfernte Programme, Verdächtiger Netzwerkverkehr. Natürlich lassen sich hier Benachrichtigungen einstellen, aber als besonderes Extra gibt es auch Plugins, die im Problemfall ausgeführt werden können.

Plugins sind im Skripte, die selbst geschrieben werden können. Zur Verfügung stehen die drei Sprachen: Bash, Powershell und Python. Plugins können per Cronjob regelmäßig ausgeführt oder eben von Alarmen getriggert werden. Dem Troubleshooting sind mit diesen drei Sprachen kaum Grenzen gesetzt. Beispielsweise könnten per SSH im Falle des Ausfalls bestimmter Webseiten die Netzwerksettings vom Server geändert oder repariert werden.

Fazit

Die Enginsight-Suite bietet eine große Palette an Sicherheits- und Überwachungsfeatures (nicht alle konnte ich in diesem Artikel vorstellen), mit denen sich einzelne Assets oder ganze Netzwerke analysieren und steuern lassen können. Dank KI-Metrik-Überwachung, Alarmen, Plugins und anderen kombinierbaren Lösungen ist hier eine großes Potential für Automatisierung, wenn alles richtig eingerichtet wird. Das Produkt ist immernoch stark in der Entwicklung und der Kontakt zum Enginsight-Team war äußerst angenehm – hier steckt viel Herzblut im Produkt.