HTTP-Tricks zur Webserver-Absicherung am Beispiel von Apache
Veröffentlicht am 06.12.2021 von DomainFactory
Wir beschäftigen uns an dieser Stelle häufig mit dem Thema Website- und Webserver-Security. Zum Beispiel erklären wir, wie Sie mögliche Angriffsflächen bei Ihrem Webserver minimieren und Server-Verzeichnisse sicher konfigurieren können.Neben direkten Angriffen auf den Server selbst nehmen Cyber-Kriminelle allerdings häufig auch die Kommunikation zwischen Webserver und Clients ins Visier. Code-Injection-Angriffe, zum Beispiel per Cross-Site-Scripting (XSS), versuchen dem Browser zusätzlich zu den angeforderten Inhalten eigenen Code unterzuschieben, der dann im Sicherheitskontext des Nutzers ausgeführt wird. Dieser Beitrag zeigt, wie Sie die Kommunikation zwischen Webserver und Browser beeinflussen können.
Webserver und Browser tauschen Nachrichten aus und bedienen sich dabei einer gemeinsamen Sprache: HTTP (Hypertext Transfer Protocol). HTTP ist ein Client-Server-Protokoll: Damit eine Interaktion zustande kommt, muss stets der Client zunächst eine Anfrage (HTTP Request) an den Server starten. Dieser beantwortet die Anfrage per HTTP Response. Beide Nachrichtentypen besitzen neben der Nutzlast (Daten) im Message Body auch einen Kopfzeilenbereich (Header) mit zugehörigen Informationen. (Lesen Sie auch unseren Artikel über HTTP-Header.)
HTTP-Methoden einschränken
Anfragen können verschiedene HTTP-Methoden verwenden. Die häufigste Request-Methode ist GET zur Anforderung von Daten vom Server. Sollen dagegen Daten (z. B. Formulardaten) zum Server geschickt werden, eignet sich die POST-Methode. Während diese Methoden vergleichsweise unkritisch sind, können andere HTTP-Methoden leicht missbraucht werden. Durch PUT und PATCH kann beispielsweise bösartiger Code auf den Server gelangen, und per DELETE-Requests können Clients Ressourcen gezielt vom Server löschen. Unsicher ist auch die TRACE-Methode für die Fehlersuche. Sie kann für einen Angriff namens Cross-Site-Tracing verwendet werden, bei dem sich Dritte möglicherweise kritische Informationen wie Authentifizierungsdaten verschaffen können. Wenn Ihre Anwendungen diese Methoden nicht benötigen, können Sie sie deaktivieren.
Bis vor nicht allzu langer Zeit gab es bei Apache nur die Möglichkeit, mittels Limit- oder LimitExcept-Direktive die Nutzung bestimmter Methoden zu beschränken. Seit Apache 2.3 existiert mit der Direktive Require ein deutlich einfacherer Weg. Um für ein Verzeichnis oder eine Location ausschließlich die Methoden GET, HEAD, POST und OPTIONS zu erlauben, schreiben Sie in der zentralen Konfiguration (oder .htaccess, falls per AllowOverride AuthConfig gestattet):
Require method GET HEAD POST OPTIONS
Benötigen Ihre Applikationen auch andere Methoden, können Sie einen RequireAny-Container nutzen, um differenziertere Bedingungen zu formulieren.
Achtung: Leider kann keiner der genannten Wege die Methode TRACE einschränken; diese wird nur von der Direktive TraceEnable beeinflusst. Wer sie deaktivieren will, muss explizit TraceEnable off angeben (Standardeinstellung ist on).
Gefährliche Skripte
Gefahren lauern auch immer dort, wo der Browser Skripte ausführt, die nicht vom Website-Betreiber stammen. Clientseitiges Scripting per JavaScript ist heute für zahlreiche Funktionalitäten unabdingbar. Im Vergleich zu serverseitigen Skripten läuft es auch wesentlich schneller und ist damit benutzerfreundlicher. Die Kehrseite ist die Möglichkeit, dem Browser etwa per XSS bösartigen Code aus anderer Quelle unterzuschieben.
Zwar befolgen Browser seit vielen Jahren standardmäßig die „Same Origin Policy“ (SOP), ein Sicherheitskonzept, nach welchem die Skripte auf einer Seite nicht auf Daten anderer Herkunft zugreifen dürfen. Dennoch finden Angreifer immer wieder Sicherheitslücken, die es ihnen erlauben, die SOP durch XSS-Attacken zu umgehen.
Besonders relevant ist hier die unzureichende Absicherung von benutzergeneriertem Input zum Beispiel in Kommentaren oder auf Profilseiten (Persistent XSS) oder in Suchformularen (Non-persistent XSS). Enthält solcher Input bösartigen Code, wird dieser womöglich beim Anzeigen ausgeführt, weil er aus Browser-Sicht die gleiche Herkunft hat wie die Webseite selbst. Solche untergeschobenen Skripte können je nach Sicherheitskontext des Aufrufenden sehr gefährlich sein, zum Beispiel bei angemeldeten Nutzern ganz ohne deren Zutun Cookies mit Authentifizierungsinformationen auslesen. Mit dem übernommenen Konto könnten Hacker dann vielleicht Daten stehlen, weitere Konten hacken oder, wenn es sich ein Admin-Konto handelt, die Website übernehmen.
Cookies schützen: HttpOnly und Secure
Ein Weg, um die Gefahr solcher Angriffe zu reduzieren, ist der Schutz von Cookies. Neben clientseitigen Methoden gibt es dafür auch Maßnahmen, die Sie als Server-Betreiber ergreifen können. Eine Möglichkeit sind die Header-Attribute HttpOnly und Secure.
Das Header-Flag HttpOnly verhindert, dass ein Cookie per JavaScript ausgelesen werden kann. Damit können viele XSS-Attacken vermieden werden. Das Secure-Flag wiederum sorgt dafür, dass ein Cookie nur über verschlüsselte Verbindungen (also über HTTPS) zum Server gesendet wird, was das Mitlesen per Man-in-the-Middle-Angriff erschwert. Cookies sollten stets das Secure-Attribut erhalten und zudem nur im Ausnahmefall, wenn JavaScript-Zugriff unbedingt erforderlich ist, ohne HttpOnly gesendet werden. Zusätzlich wird u. a. empfohlen, ihre Gültigkeitsdauer mittels Expires- oder Max-Age-Attribut so kurz wie möglich zu halten.
Zur Übermittlung und Ausgestaltung von Cookies dient der HTTP-Header Set-Cookie.
Bei Apache generieren Sie Set-Cookie-Headers mittels der Direktive Header, die auch in .htaccess-Dateien verfügbar ist. Das folgende Beispiel fügt die genannten Attribute an alle Set-Cookie-Header an, deren Cookie-Name mit „session_id“ beginnt:
<IfModule mod_headers.c>
Header always edit Set-Cookie ^(session_id.*)$ "$1; Max-Age=900; Secure; HttpOnly"
</IfModule>
Das Ergebnis sieht also so aus:
Set-Cookie: session_id=123abc456; Max-Age=900; Secure; HttpOnly
Weitere der Sicherheit dienliche Header sind die Folgenden:
#(Re-)aktiviert XSS-Filter aktueller Browser:
Header set X-XSS-Protection "1; mode=block"
#Frame-Einbettung beschränken gegen Clickjacking-Attacken
Header always append X-Frame-Options SAMEORIGIN
#Blockiert Content-Sniffing
Header set X-Content-Type-Options nosniff
(Mehr Infos zum Content-Sniffing finden Sie in unserem Artikel: Risiken und Tipps zum Schutz vor Content Type Sniffing.)
Content Security Policy
Die genannten Security-Header können die Sicherheit erhöhen, bleiben aber Stückwerk. Um XSS-, Clickjacking- und andere Code-Injection-Angriffe zu verhindern, entwickelte Mozilla ein als „Content Security Policy“ (CSP) bezeichnetes Sicherheitskonzept, das heute von allen modernen Browsern unterstützt wird. Eine W3C-Empfehlung befindet sich in der Ausarbeitung.
Das Konzept: Um nicht autorisierte Skriptausführungen zu verhindern, soll sämtlicher JavaScript-Code in externe Dateien (oder alternativ in gehashte Code-Blöcke) ausgelagert und so strikt von HTML-Inhalten (auch dynamisch generierten) getrennt werden. Externe Skriptingcode-Dateien können nur aus einer vertrauenswürdigen Domäne aufgerufen werden. Der dynamische Inline-Aufruf von JavaScript-Code und CSS-Statements in HTML-/PHP-Dateien und die dynamische Code-Ausführung über bestimmte Funktionen sind nicht gestattet. Ein Browser setzt diese CSP um, wenn er einen oder mehrere Content-Security-Policy-Header in der Server-Antwort vorfindet. In diesen Headern teilt der Server dem Client konkrete Policy-Direktiven mit, insbesondere die vertrauenswürdigen Speicherorte für Skripte, Stylesheets, Fonts, Bilder, Objekte (Plugins) etc. Das folgende Beispiel verbietet die Inline-Ausführung von JavaScript-Code und verlangt, dass jegliche Ressourcen außer Bildern vom Ursprungsserver geladen werden (gleiche Domain, auch keine abweichende Subdomain gestattet):
Content-Security-Policy-Report-Only: default-src 'self'; img-src *;
Auch Sie sollten für Ihre Inhalte eine CSP definieren und einsetzen.
Übrigens: Diese kann auch im HTML-Dokument per Meta-Tag aktiviert werden.