Oxid Shop absichern: Funktionierende HTTP Security Header für CSP, HSTS und Co.

(Kommentare: 0)

Abbildung HAcker mit abgezogenem Netzwerkkabel
© beccarra / Shutterstock.com

Der ein oder andere wird bei einem Sicherheitscheck seiner Website eine böse Überraschung erleben. Hat man soweit keine Maßnahmen ergriffen, wird einem das Mozilla Observatorium mit ziemlicher Wahrscheinlichkeit eine vernichtende Bewertung um die Ohren hauen. Doch keine Sorge: Das eigene Ranking lässt sich in den meisten Fällen schon mit wenigen Maßnahmen auf ein durchaus akzeptables Level schrauben.

Zahlreiche Unternehmen lassen Ihre Websites und Onlineshops auf Apache Servern laufen. Somit steht ihnen in Form der .htaccess-Datei, über die sich die Konfiguration des Apache Webservers beeinflussen lässt, eine Möglichkeit zur Einrichtung der meisten sicherheitsrelevanten Direktiven zur Verfügung. Leider gilt das nicht für per FCGI erzeugte Inhalte (PHP, Perl, usw.). Hier müssen die Header über die eingesetzte Web Applikation gesteuert werden. Das ist ein Umstand, der uns beispielsweise bei dem beliebten Oxid-Hoster Profihost begegnet. Damit die Anweisungen auch für unseren Oxid Shop greifen, muss also ein anderer Ansatz gewählt werden. Hierfür ist die Datei functions.php im Ordner /modules sehr gut geeignet. Hier hinterlegen wir unsere Anweisungen updatesicher als PHP Header - die Einträge in der .htaccess werden somit nicht benötigt.

Als Grund- und Vorlage (nicht nur) für die .htaccess-Anweisungen kann das hervorragende Framework HTML5 Boilerplate herangezogen werden. Das Framework bietet auch Konfigurationsdateien für IIS, Lightttpd oder Nginx; wir beschränken uns in diesem Artikel aber auf die Möglichkeiten innerhalb der Apache-Umgebung.

Grundvoraussetzung und erste Anlaufstelle unserer To-do-Liste muss ein erfolgreich eingerichtetes SSL-Zertifikat sein - egal, ob Shop oder Website. Ohne das sind auch alle weiteren Maßnahmen mehr oder weniger sinnfrei. Deshalb sollte zunächst sichergestellt werden, dass die Seite ausschließlich über HTTPS erreichbar ist. Die notwendigen Rewrite Regeln sind die folgenden:

a) Rewrite Engine starten und konfigurieren
<IfModule mod_rewrite.c>

    # Rewrite Engine aktivieren, damit unsere Regeln greifen können
    RewriteEngine On	

    # Symbolischen Links folgen
    Options +FollowSymlinks	

    # Alternative, falls der Provider "FollowSymlinks" nicht unterstützt
    # Options +SymLinksIfOwnerMatch	

    # Bei manchen Providern ist das Setzen der RewriteBase erforderlich
    # RewriteBase /	

    # Abhängig von der Server-Konfig. müssen ggf. RewriteOptions gesetzt werden 
    # s. https://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriteoptions
    # RewriteOptions <options>	

    # %{ENV:PROTO} Variable setzen, damit die Umschreibungen automatisch
    # mit dem entsprechenden Protokoll umgeleitet werden http oder https)
    RewriteCond %{HTTPS} =on
    RewriteRule ^ - [env=proto:https]
    RewriteCond %{HTTPS} !=on
    RewriteRule ^ - [env=proto:http]

</IfModule>
b) Aufruf per HTTPS erzwingen
<IfModule mod_rewrite.c>
	# Rewrite Engine an
	RewriteEngine On
	# Prüfen, ob nicht schon über HTTPS zugegriffen wird
	RewriteCond %{HTTPS} !=on
	# Weiterleitung zur selben Seite, unter der Verwendung von HTTPS
	RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>

Ist das erledigt, können wir uns der Implementierung der Security Header widmen. Die wichtigsten Punkte, auf die wir in diesem Artikel eingehen werden, sind folgende:

Im Detail:

Cross-Site-Scripting verhindern (X-XSS-Protection)

Mit dieser Anweisung wird der in den meisten Webbrowsern integrierte Cross-Site-Scripting-Filter (XSS) reaktiviert. Dieser ist zwar standardmäßig aktiviert, kann aber vom Benutzer manuell abgeschaltet werden. Speziell für den IE gilt die Anweisung "1". Mit "mode=block" wird verhindert, dass der Browser die Webseite rendert, falls ein potenzieller XSS-Angriff vom Filter erkannt werden sollte.

.htaccess Anweisung:

<IfModule mod_headers.c>
    Header set X-XSS-Protection "1; mode=block"
    # Den Header nur für HTML-Dokumente und nicht für die anderen Ressourcen senden
	<FilesMatch "\.(appcache|atom|bbaw|bmp|crx|css|cur|eot|f4[abpv]|flv|geojson|gif|htc|ico|jpe?g|js|json(ld)?|m4[av]|manifest|map|mp4|oex|og[agv]|opus|otf|pdf|png|rdf|rss|safariextz|svgz?|swf|topojson|tt[cf]|txt|vcard|vcf|vtt|webapp|web[mp]|webmanifest|woff2?|xloc|xml|xpi)$">
		Header unset X-XSS-Protection
	</FilesMatch>
</IfModule>

PHP Header:

<?php  
	header("X-XSS-Protection: 1; mode=block");
?>

HTTP Strict Transport Security (HSTS)

Wenn ein Benutzer in seinem Browser eine Adresse eingibt, bleibt für den Angreifer eine Möglichkeit, die ursprüngliche HTTP-Verbindung umzuleiten - selbst wenn der Server an sich auf die sichere HTTPS-Version der Website weiterleitet.

Die folgende Anweisung stellt sicher, dass der Browser ausschließlich über HTTPS eine Verbindung zum Server herstellt, unabhängig davon, was der Benutzer in die Adressleiste eingibt.

.htaccess Anweisung:

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

PHP Header:

<?php  
	header("Strict-Transport-Security:max-age=15768000");
?>

"Max-age" legt dabei eine Gültigkeit von sechs Monaten (in Sekunden) fest, was das absolute Mindestmaß darstellt.

X-Content-Type-Options: Das Reduzieren von MIME-Typ-Sicherheitsrisiken

Um vollständigen Schutz zu bieten sollten Sie, wenn Sie Ihren Shop vor Cross-Site-Scripting-Angriffen schützen wollen, unbedingt den nosniff-Header mitschicken. Mit der folgenden Anweisung wird dem Browser signalisiert, dass die MIME-Typen respektiert werden sollen.

.htaccess Anweisung:

<IfModule mod_headers.c>
	Header set X-Content-Type-Options "nosniff"
</IfModule>

PHP Header:

<?php
	header('X-Content-Type-Options: nosniff');
?>

Content Security Policy (CSP)

CSP reduziert das Risiko von Cross-Site-Scripting und anderen Angriffen, wie Content-Injection. Dazu können diverse Sicherheitsrichtlinien festgelegt werden, die vertrauenswürdige Inhaltsquellen für die eigene Seite auf eine Whitelist setzen.

Das Thema ist komplex, und kann aufgrund des individuellen Aufbaus eines Shops nicht pauschalisiert werden. Der untere Code beschränkt sich also nur auf die notwendigen Direktiven.

Weiterführende Infos finden sich beispielsweise auf sitepoint.com und mozilla.org.

.htaccess Anweisung:

<IfModule mod_headers.c>	
	# Theoretische Mindestanweisung: 
	# Header set Content-Security-Policy "script-src 'self'; object-src 'self'"
	# Für Oxid muss zusätzlich 'unsafe-inline' und 'unsafe-eval' gesetzt werden,
	# sowie verschiedene externe URLs wie z.B. paypal.com paypalobjects.com.
	Header set Content-Security-Policy "script-src 'self' 'unsafe-inline' *.whitelist-url-01.com *.whitelist-url-02.com  'unsafe-eval';"

	# Den Header nur für HTML-Dokumente und nicht für die anderen Ressourcen senden
	<FilesMatch "\.(appcache|atom|bbaw|bmp|crx|css|cur|eot|f4[abpv]|flv|geojson|gif|htc|ico|jpe?g|js|json(ld)?|m4[av]|manifest|map|mp4|oex|og[agv]|opus|otf|pdf|png|rdf|rss|safariextz|svgz?|swf|topojson|tt[cf]|txt|vcard|vcf|vtt|webapp|web[mp]|webmanifest|woff2?|xloc|xml|xpi)$">
	Header unset Content-Security-Policy
	</FilesMatch>
</IfModule>

PHP Header:

//Richtlinien definieren
$cspHeader = "Content-Security-Policy:".
    "default-src 'none'; ". // Alle Anfragen standardmäßig ablehnen, und nachfolgend sukzessive ergänzen 
    "connect-src 'self'; ". // XMLHttpRequest (AJAX requesst), WebSocket oder EventSource
    "font-src 'self'; ".
    "img-src 'self' data:; ". // "data:" für Data-URLs, wiez.B. bei Base64 Images
    "media-src 'self'; ".
    "object-src 'self'; ".
    "script-src 'self' 'unsafe-inline'*.whitelist-url-01.com *.whitelist-url-02.com  'unsafe-eval'; ". 
    "style-src 'self' 'unsafe-inline'; ". // Inline CSS erlauben
    "frame-ancestors 'self'; ". //Unterbindet Click-Jacking
    "frame-src 'self' *.youtube.com *.paypal.com *.paypalobjects.com; ". // Gültige Frame-Quellen ink. YouTube-Videos und PayPal Paywall
    "worker-src 'self'; ".
    "form-action 'self' *.paypal.com *.paypalobjects.com; ". // Inkl. der für PP Paywall notwendige Domains
    "base-uri 'self';";

//Header senden
header($cspHeader);

Mit diesen Anweisungen sollten die größten potentiellen Sicherheitslecks gestopft sein, und das Moz Observatorium unseren Shop mit einem Ranking im Bereich "B" bewerten.

Was durchaus akzeptabel ist.

Viel Erfolg!

Update 11.03.2018: Security Header in Wordpress aktivieren

Um HSTS, CSP und Co. in Wordpress zum Laufen zu kriegen, kann in der functions.php des (Child-)Themes eine eigene Funktion deklariert werden.

Wir geben ihr den Namen add_security_headers, und weisen sie dem Action-Hook mit der Bezeichnung send_headers zu.

functions.php:

function add_security_headers() {

    // Header 1 ...
    // Header 2 ...
    // Header 3 ...
}

add_action( 'send_headers', 'add_security_headers' );

Zurück

Einen Kommentar schreiben

Was ist die Summe aus 6 und 2?