4 Min

Cross Site Scripting

Cross-Site Scripting (XSS) ist eine Sicherheitslücke, bei der Angreifer schädlichen Code (meist JavaScript) in Webseiten einschleusen, der dann von anderen Benutzern im Kontext dieser Website ausgeführt wird. XSS wird möglich, wenn eine Webseite unsichere Benutzereingaben ohne ausreichende Überprüfung oder Filterung in die HTML-Ausgabe einfügt.

Wie funktioniert XSS?

XSS basiert darauf, dass eine Anwendung unkontrollierten Code oder schädliche Skripte in ihren Output einbettet. Wenn dieser schädliche Code im Browser eines anderen Benutzers ausgeführt wird, kann er eine Vielzahl von Aktionen ausführen, z.B. Daten stehlen, Cookies auslesen oder andere schädliche Aktivitäten im Kontext der Webseite ausführen.

Drei Haupttypen von XSS:

  1. Stored XSS (persistentes XSS):
    • Der schädliche Code wird dauerhaft in der Datenbank oder im Backend der Webanwendung gespeichert (z.B. durch ein Formular).
    • Wenn ein anderer Benutzer die Seite aufruft, wird der schädliche Code aus der Datenbank geladen und im Browser des Opfers ausgeführt.
    • Beispiel: Ein Benutzer postet einen Kommentar in einem Forum mit schädlichem JavaScript. Andere Benutzer, die den Kommentar lesen, führen unwissentlich dieses Skript aus.
  2. Reflected XSS (reflektiertes XSS):
    • Der schädliche Code wird nicht gespeichert, sondern sofort über einen manipulierten Link oder eine URL an den Server gesendet und dann an den Browser zurückgeschickt, ohne dass der Server ihn filtert.
    • Der Angriff wird in der Regel über manipulierte Links durchgeführt. Wenn der Benutzer diesen Link anklickt, wird das bösartige Skript in seinem Browser ausgeführt.
    • Beispiel: Ein Benutzer klickt auf einen Link wie http://example.com/search?query=<script>alert('Hacked')</script>.
  3. DOM-based XSS:
    • Hier wird das bösartige Skript direkt im Browser ausgeführt, ohne dass es über den Server geht. Dies geschieht, wenn die Client-seitige JavaScript-Logik auf unsichere Weise mit den DOM-Elementen interagiert.
    • Beispiel: Wenn die JavaScript-Anwendung unsichere Benutzereingaben in das DOM einfügt, wie z.B. durch innerHTML, ohne die Eingaben richtig zu filtern.

Wo kann XSS konkrete Schäden anrichten?

XSS kann an vielen Stellen in einer Webanwendung zu erheblichen Schäden führen:

  1. Diebstahl von Session-Cookies:
    • Ein Angreifer kann über ein XSS-Skript Session-Cookies von Benutzern stehlen und damit ihre Sitzung übernehmen.
    • Beispiel: Der Angreifer liest das Cookie per JavaScript aus (document.cookie) und sendet es an seinen eigenen Server.
  2. Identitätsdiebstahl und Account-Übernahme:
    • Durch XSS kann ein Angreifer auf Benutzerdaten zugreifen oder sogar Benutzer-Accounts übernehmen, indem er schädlichen Code injiziert und Benutzerdaten ausliest.
  3. Phishing-Angriffe:
    • Angreifer können gefälschte Login-Formulare oder andere Phishing-Seiten auf legitimen Webseiten platzieren, um Benutzernamen, Passwörter und andere sensible Informationen zu stehlen.
  4. Verwüstung von Webseiten-Inhalten:
    • Der Angreifer kann den Inhalt einer Webseite verändern, Popups anzeigen, Weiterleitungen auslösen oder die Seite völlig unbenutzbar machen.
  5. Verbreitung von Malware:
    • Schädliche Skripte können verwendet werden, um Benutzer dazu zu bringen, Malware herunterzuladen, indem automatisch schädliche Dateien von Dritten Servern geladen werden.
  6. Missbrauch der API:
    • Wenn eine Webseite APIs wie Google Maps, Payment Gateways oder soziale Netzwerke verwendet, kann XSS diese APIs manipulieren und unautorisierte Aktionen im Namen des Benutzers durchführen.

Wie schütze ich meine User vor XSS?

Um als Webentwickler XSS zu verhindern, sind eine Vielzahl von Sicherheitsmaßnahmen nötig. Die wichtigsten Methoden zur Vorbeugung sind:

1. Eingabevalidierung und -filterung

  • Input-Validierung: Stellen Sie sicher, dass alle Benutzereingaben geprüft und nur die erwarteten Werte zugelassen werden (z.B. keine HTML-Tags in Textfeldern).
  • Whitelist statt Blacklist: Verwenden Sie eine Positivliste (Whitelist) von zugelassenen Eingaben, statt zu versuchen, nur schädliche Eingaben zu blockieren.
  • Filterung: Alle Benutzereingaben sollten auf unerwünschte Zeichen überprüft und ggf. gefiltert werden. Das ist besonders wichtig bei Zeichen wie <, >, &, " und ', die in HTML und JavaScript eine besondere Bedeutung haben.

2. Escape von Ausgaben (Output Encoding)

  • Wenn Benutzereingaben auf der Webseite zurückgegeben werden (z.B. in einem Kommentar), sollten sie immer in einer sicheren Form “escaped” werden, bevor sie ins HTML eingefügt werden.
  • Für HTML sollte man die Sonderzeichen &, <, >, ", ' durch HTML-Entitäten ersetzen:
    • < wird zu &lt;
    • > wird zu &gt;
    • & wird zu &amp;
    • ", ' wird zu &quot; oder &#039;
  • Beispiel in JavaScript:
    function escapeHTML(text) {
        const div = document.createElement('div');
        div.appendChild(document.createTextNode(text));
        return div.innerHTML;
    }
    

3. Verwendung von Sicherheits-Headern

  • Content Security Policy (CSP): CSP ist ein Sicherheitsmechanismus, der festlegt, welche Ressourcen (wie Skripte, Bilder, Stylesheets) auf einer Webseite geladen und ausgeführt werden dürfen.
    • Ein guter CSP verhindert, dass Inline-Skripte (z.B. <script>-Tags oder Event-Handler wie onclick) und unsichere Quellen wie eval() oder Daten-URLs ausgeführt werden.
    • Beispiel für eine CSP-Policy:
      Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'none';
      

4. Vermeidung von gefährlichen Funktionen

  • Verwenden Sie keine unsicheren Funktionen wie innerHTML, document.write, oder eval(), um Benutzereingaben in das DOM einzufügen, da diese Funktionen ungesicherten Code direkt ausführen können.
  • Stattdessen sollten sichere Methoden wie textContent oder setAttribute() verwendet werden, die die Eingabe nicht als HTML interpretieren.

  • Beispiel für sichere DOM-Manipulation:
    const div = document.getElementById('output');
    div.textContent = 'Dies ist sicherer Text'; // Sichere Methode statt innerHTML
    

5. Verwenden von sicheren Bibliotheken

  • Viele moderne Frameworks und Bibliotheken wie React, Vue.js oder Angular bieten eingebaute Schutzmechanismen gegen XSS-Angriffe. Diese Frameworks “escapen” Benutzereingaben automatisch, sodass XSS deutlich schwerer zu implementieren ist.

  • Beispiel in React:

    const safeText = "<script>alert('XSS')</script>";
    return <div>{safeText}</div>; // React escaped automatisch den Script-Tag
    
  • Verwenden Sie Secure, HttpOnly und SameSite Flags für Cookies, um sie vor XSS zu schützen:
    • Secure: Cookie wird nur über HTTPS übertragen.
    • HttpOnly: Cookie kann nicht von JavaScript gelesen werden (schützt vor Diebstahl durch XSS).
    • SameSite: Verhindert das Senden des Cookies in Cross-Site-Anfragen (schützt vor CSRF).

7. Regelmäßiges Security-Testing

  • Verwenden Sie Security-Tools, um XSS-Tests durchzuführen. Dazu gehören Tools wie OWASP ZAP oder Burp Suite, die Schwachstellen in Webanwendungen aufdecken können.
  • Regelmäßige Sicherheitsüberprüfungen, insbesondere nach Änderungen im Frontend-Code, sind unerlässlich, um neue Angriffsvektoren zu identifizieren.

Fazit

XSS ist eine der häufigsten und gefährlichsten Sicherheitslücken im Web. Als Webentwickler ist es entscheidend, Benutzereingaben sorgfältig zu validieren und zu escapen, um zu verhindern, dass schädlicher Code ausgeführt wird. Durch den Einsatz von modernen Web-Techniken wie Content Security Policies (CSP), sicheren Funktionen zur DOM-Manipulation und Frameworks mit eingebauten Sicherheitsmechanismen kann das Risiko von XSS erheblich minimiert werden.

Updated: