Wir entwickeln moderne Web Applikationen und bieten erstklassigen Kunden Support

IN LI TW

XSS-Lücken erkennen und beheben

11. Juli 2024
Development

In der heutigen digitalen Welt, in der Online-Dienste und Webanwendungen eine zentrale Rolle in unserem täglichen Leben spielen, wird die Sicherheit von Webseiten immer wichtiger. Eine der gefährlichsten und zugleich am häufigsten übersehenen Bedrohungen ist Cross-Site Scripting, besser bekannt als XSS. Diese Art von Angriff zielt darauf ab, Schwachstellen in Webanwendungen auszunutzen, um bösartigen Code in die Browser der Nutzer einzuschleusen.

XSS-Angriffe können schwerwiegende Folgen haben: Von der Übernahme von Benutzerkonten und dem Diebstahl sensibler Daten bis hin zur Manipulation von Webseiteninhalten und der Verbreitung von Malware.

Einfaches Beispiel

Um die Funktionsweise eines XSS-Angriffs besser zu verstehen, betrachten wir ein konkretes Beispiel. Stellen wir uns eine einfache Webanwendung vor, die ein Gästebuch enthält, in dem Besucher Nachrichten hinterlassen können.

1<form action="/submit_message" method="POST">
2 <label for="message">Nachricht:</label>
3 <input type="text" id="message" name="message">
4 <input type="submit" value="Absenden">
5</form>

Ausgabe ohne Eingabensicherung:

1<div id="guestbook">
2 <!-- Beispiel für eine gespeicherte Nachricht -->
3 <p>Nachricht: Hallo, dies ist ein Test!</p>
4</div>

Bösartige Eingabe:

1<script>alert('XSS-Angriff!');</script>

Bei fehlender Eingabensicherung würde der Javascript-Alert ausgeführt werden. Die Folge der Code würde ausgeführt werden. Im Beispiel zwar nur ein Alert, in freien Wildbahn werden diese Lücken in der Regel aber für das Ausführen von Schade-Code oder zum Datendiebstahl genutzt.

Wie schütze ich mich vor XSS-Lücken

Es gibt mehrere Varianten sich vor XSS-Lücken zu schützen. Am effektivsten erweisen sich:

  • Eingabeverifizierung: Alle Benutzereingaben sollten gründlich überprüft und bereinigt werden, bevor sie verarbeitet oder angezeigt werden.

  • Ausgabeverschlüsselung: Benutzereingaben sollten mit HTML-Entitäten verschlüsselt werden, um sicherzustellen, dass sie als Text und nicht als Code interpretiert werden.

  • Content Security Policy (CSP): Eine CSP kann helfen, das Ausführen von nicht vertrauenswürdigem Skript-Code zu verhindern.

Eingabeverifizierung

Es ist immer eine gute Idee, genau zu überprüfen, welche Daten gespeichert werden.

Für NodeJS kann dafür beispielsweise sanitize-html genutzt werden, um die Daten bereits bei der Eingabe zu cleanen.

Im Laravel-Ökosystem existieren zahlreiche Packages z.B: Laravel-XSS-Protection.

In der Regel kann man sich im PHP Context auch strikt durch folgenden Code Snippet helfen:

1strip_tags("<script>alert(1);</script>");

Sollte dies aus Gründen erforderlich sein, dass hier kein Cleanup stattfindet (z.B. Nutzung von WYSIWYG-Editoren) gibt es mit CSP und Encoding noch zwei alternative Ansätze.

Ausgabeverschlüsselung = Encoding

Darunter steht man die Konvertierung von potentiell gefährlichen Zeichen z.B. < und > in deren HTML Equivalent. &gt; und &lt;

Dies kann in meisten Fällen unkompliziert und einfach erfolgen:

Javascript (Vanilla)

1function encodeHTML(str) {
2 const div = document.createElement('div');
3 div.appendChild(document.createTextNode(str));
4 return div.innerHTML;
5}

PHP

1$output = htmlspecialchars("<script>alert(1);</script>");

Sonderfall Markdown

Wenn man Markdown verwendet, sollte man sich darüber im Klaren sein, dass Markdown standardmäßig die Ausführung von Skripten unterstützt, was zu einem inhärenten XSS-Problem führen kann. In Verbindung mit Laravel gibt es jedoch eine nützliche Hilfsmethode, die dieses Problem beheben kann:

1use Illuminate\Support\Str;
2 
3Str::inlineMarkdown('Inject: <script>alert("Hello XSS!")</script>', [
4 'html_input' => 'strip',
5 'allow_unsafe_links' => false,
6]);

Statamic Hilfsfunktionen

Bei Statamic gibt zusätzlich dazu noch Modifier die das Ausgabeergebnis "sanitizen"

1<a href="{{ my_link | sanitize }}">My Link</a>

Content Security Policy (CSP)

Content Security Policy (CSP) ist eine leistungsstarke Sicherheitsfunktion, die von Webentwicklern verwendet werden kann, um eine zusätzliche Schutzebene gegen verschiedene Arten von Angriffen wie Cross-Site Scripting (XSS) und Dateninjektionsangriffe zu bieten. CSP ermöglicht es Entwicklern, eine genaue Richtlinie zu definieren, die angibt, welche Inhalte von welchen Quellen auf ihrer Webseite geladen und ausgeführt werden dürfen. Indem Entwickler nur vertrauenswürdige Quellen für Skripte, Stylesheets und andere Ressourcen zulassen, können sie das Risiko reduzieren, dass bösartige Inhalte auf ihre Webseiten injiziert und ausgeführt werden.

CSP wird im HTTP-Header der Webseite konfiguriert und bietet somit eine flexible Möglichkeit, Sicherheitsrichtlinien ohne Änderungen am bestehenden Code zu implementieren. Diese Präventivmaßnahme ist ein wesentlicher Bestandteil moderner Websicherheit und trägt erheblich dazu bei, die Integrität und Sicherheit von Webanwendungen zu gewährleisten.

In Laravel und NodeJS Applikationen kann dies einfach durch eine Middleware realisiert werden:

1public function handle(Request $request, Closure $next) {
2 
3 // CSP-Header mit dem Nonce-Wert setzen
4 $response = $next($request);
5 $response->headers->set('Content-Security-Policy', "script-src 'self' https://www.youtube.com;");
6 
7 return $response;
8}

Manchmal hat man auch den Bedarf inline-scripts auszuführen. Hierfür gibt es zwei Varianten. Eine Möglichkeit bestünde darin unsafe-eval in der CSP zu aktiveren. Dies ermöglicht aber wieder, dass potentielle XSS-Lücken ausgenutzt werden können.

Eine Alternative besteht darin, <script>-Tags mit einem Nonce zu versehen, welcher ebenfalls im Header bekannt gegeben wird. Damit wird dem Browser mitgeteilt, dass diese Skripte bekannt sind und ausgeführt werden können.

Die Erweiterung für die vorherige Middleware würde wiefolgt aussehen:

1public function handle(Request $request, Closure $next) {
2 
3 $nonce = Str::random(16);
4 
5 // CSP-Header mit dem Nonce-Wert setzen
6 $response = $next($request);
7 $response->headers->set('Content-Security-Policy', "script-src 'self' 'nonce-$nonce' https://www.youtube.com;");
8 
9 // Nonce-Wert muss für inline code verwendet werden
10 session(['cspnonce' => $nonce]);
11 
12 return $response;
13}

Im HTML-Code muss zusätzlich ein nonce attribute hinzugefügt werden:

1<script nonce="{{ nonce }}">
2 alert("Ich bin sicher");
3</script>

Für Statamic empfiehlt es sich, ein benutzerdefiniertes Tag-Element zu erstellen, das die gewünschte Aufgabe übernimmt und die entsprechenden Parameter weiterleitet. Dieses Tag-Element muss jedoch eigenständig entwickelt werden, um die spezifischen Anforderungen und Funktionen zu erfüllen.

XSS Lücken erkennen

Das Erkennen von Cross-Site Scripting (XSS)-Schwachstellen ist ein entscheidender Schritt, um die Sicherheit von Webanwendungen zu gewährleisten. Entwickler und Sicherheitsexperten nutzen eine Vielzahl von Tools, um potenzielle XSS-Angriffe zu identifizieren und zu verhindern. Automatisierte Scanner wie OWASP ZAP, Burp Suite und Acunetix durchsuchen den Code nach bekannten Schwachstellen und testen Eingabefelder, um festzustellen, ob bösartige Skripte eingeschleust werden können. Diese Tools analysieren Webseiten auf unsichere Praktiken und bieten detaillierte Berichte sowie Empfehlungen zur Behebung der gefundenen Sicherheitslücken. Darüber hinaus können Entwickler auch statische Codeanalyse-Tools wie ESLint mit spezifischen Plugins verwenden, um Sicherheitslücken bereits während der Entwicklungsphase zu erkennen. Durch den Einsatz dieser Tools wird die Wahrscheinlichkeit, XSS-Schwachstellen zu übersehen, erheblich reduziert, was zu einer sichereren und robusteren Webanwendung führt.

Nützliches Tool XSStrike

Mittels des Command-Line Tool XSStrike lässt sich die eigene Seite schnell scannen und auf potentielle Lücken untersuchen. Das Tool unterstützt eine Reihe von nützlichen Optionen und ist schnell einsatzbereit

Installation von XSStrike

1$ git clone https://github.com/s0md3v/XSStrike.git
2$ cd XSStrike
3$ pip3 install -r requirements.txt

Testing einer Seite mit XSStrike:

1$ python3 xsstrike.py -u URL

Zusammenfassung

Cross-Site Scripting (XSS) stellt eine erhebliche Bedrohung für die Sicherheit von Webanwendungen dar. Diese Angriffe können sensible Daten kompromittieren, Benutzerkonten übernehmen und die Integrität von Webseiten gefährden. Die Vielfalt der XSS-Angriffe, von reflektiert über gespeichert bis hin zu DOM-basiert, zeigt die Notwendigkeit eines umfassenden Sicherheitsansatzes. Entwickler müssen bewährte Sicherheitspraktiken anwenden, wie Eingabeverifizierung, Ausgabeverschlüsselung und die Implementierung von Content Security Policies (CSP). Zudem spielen automatisierte Sicherheitswerkzeuge eine wichtige Rolle bei der Erkennung und Prävention von XSS-Schwachstellen. Durch das Bewusstsein für die Gefahren und die Umsetzung geeigneter Schutzmaßnahmen können Entwickler und Organisationen ihre Webanwendungen wirksam gegen XSS-Angriffe verteidigen und somit die Sicherheit und das Vertrauen der Benutzer gewährleisten.