Articles

2. XSS never dies

Planted August 31, 2025

Logo

XSS never dies – Warum Cross-Site Scripting nicht ausstirbt

Cross-Site Scripting, kurz XSS, ist eine der ältesten bekannten Web-Schwachstellen – und trotzdem finden wir sie auch heute noch regelmäßig in modernen Anwendungen. Seit den frühen 2000er Jahren begleitet sie Sicherheitsforscher, Entwickler und Bug-Bounty-Hunter gleichermaßen. Aber warum ist das so?

Was ist XSS?

Bei XSS handelt es sich um das Einschleusen von JavaScript-Code in eine Webseite, die dann im Browser des Opfers ausgeführt wird. Das perfide daran: Der Code läuft mit denselben Rechten wie die legitime Webseite. Dadurch können Angreifer:

  • Cookies und Session-Tokens stehlen
  • Nutzeraktionen manipulieren
  • Accounts übernehmen
  • Inhalte im Namen des Opfers verändern
  • Opfer auf andere Webseiten weiterleiten.

Kurz gesagt: Der Browser des Opfers führt den Code des Angreifers aus – und öffnet damit die Tür zu einer Vielzahl von Angriffsszenarien.

Einfaches Beispiel

Ein Blog mit einem Kommentarformular speichert Nutzerkommentare und zeigt sie ohne Filterung wieder an:

<!-- Kommentar wird direkt ausgegeben -->
<div class="comment">
  Benutzer schrieb: <span>NAME</span>
</div>

Gibt ein Angreifer statt seines Namens folgenden Wert ein:

<script>alert('XSS!');</script>

wird dieses Script beim Aufruf der Seite jedes Mal ausgeführt.

Das ist ein klassisches stored XSS.


Warum stirbt XSS nicht aus?

Obwohl XSS seit über 20 Jahren bekannt ist, bleibt es ein Dauerbrenner in Penetrationstests, Bug-Bounty-Programmen und CVEs. Gründe dafür gibt es viele:

  1. Komplexe Eingaben
    Webanwendungen verarbeiten unzählige Felder, Formulare, Kommentare und Suchanfragen. Irgendwo wird fast immer ein Sonderfall übersehen.

    Beispiel: Ein Suchfeld erlaubt Eingaben wie "><img src=x onerror=alert(1)>. Wird das Ergebnis unescaped in die Seite eingefügt, haben wir eine reflektierte XSS.

  2. Frameworks helfen – aber nicht perfekt
    Moderne Frameworks wie React, Angular oder Vue bringen Schutzmechanismen mit. Werden sie aber falsch eingesetzt, können trotzdem Lücken entstehen.

    Beispiel: In React sollte man niemals dangerouslySetInnerHTML verwenden, ohne die Eingabe vorher zu säubern. Tut man es doch, kann direkt JavaScript ausgeführt werden.

  3. Legacy-Code
    Viele Anwendungen basieren auf altem Code, der nie komplett modernisiert wird. Alte Fehler bleiben erhalten und tauchen in neuen Kontexten wieder auf.

    Beispiel: JSP- oder PHP-Anwendungen aus den 2000ern, die echo $_GET['q']; oder <%= request.getParameter("q") %> ohne Encoding ausgeben.

  4. Neue Features
    Mit jeder neuen Browser-API oder Funktionalität entstehen auch neue Angriffsflächen.

    Beispiel: XSS über SVG-Dateien mit eingebetteten Event-Handlern (<svg onload=alert(1)>) oder moderne HTML5-Attribute.

Das Fazit: Solange es dynamische Webseiten gibt, wird es auch XSS geben.


Praxisbeispiel: CVE-2024-47950 in TeamCity

Ein Beispiel aus dem Jahr 2024 zeigt, wie real das Problem ist. Ich habe eine Schwachstelle in JetBrains TeamCity gefunden – dokumentiert als CVE-2024-47950 (technische Details gibt es hier).

TeamCity ist ein weit verbreitetes CI/CD-Tool, das in Unternehmen für Software-Builds und Deployments genutzt wird.

Die Schwachstelle war eine stored XSS. Das bedeutet, dass ein Angreifer JavaScript-Code einschleusen konnte, der dauerhaft in der Anwendung gespeichert wurde. Immer wenn andere Nutzer oder Administratoren die betroffene Seite aufriefen, wurde der Code automatisch ausgeführt.

Warum ist das gefährlich?

  • Persistenz: Der Angriff wirkt dauerhaft – jeder Nutzer der Seite ist betroffen.
  • Hoher Impact: Besonders im Admin-Backend kann XSS katastrophale Folgen haben.
  • Mögliche Folgen: Session-Übernahme, Zugriff auf vertrauliche Daten, Manipulation ganzer Build-Pipelines.

Die Schwachstelle wurde von JetBrains zeitnah behoben und ist seit über einem Jahr gefixt. Den Proof of Concept habe ich in einem separaten Blog-Post veröffentlicht.

Dieses Beispiel zeigt eindrucksvoll: Selbst moderne und sicherheitskritische Software ist nicht immun gegen XSS.


Was lernen wir daraus?

XSS macht deutlich, dass IT-Sicherheit kein einmal gelöstes Problem ist. Wir müssen kontinuierlich wachsam bleiben. Konkret bedeutet das:

  • Eingaben strikt validieren
  • Ausgaben korrekt escapen (HTML, JavaScript, CSS, URL – jeweils kontextabhängig!)
  • Content Security Policy (CSP) einsetzen
  • Frameworks verstehen und sicher einsetzen

Ein Beispiel für korrektes Escaping in PHP:

<?php echo htmlspecialchars($_GET['q'], ENT_QUOTES, 'UTF-8'); ?>

Und am wichtigsten: Sensibilisierung von Entwicklern. Nur so vermeiden wir, dass alte Fehler in neuen Projekten immer wieder auftauchen.


Fazit

XSS never dies” ist mehr als nur ein Spruch. Es ist eine Erinnerung daran, dass Sicherheit im Web ein dauerhafter Prozess ist.

Wer XSS versteht und ernst nimmt, kann es erfolgreich verhindern – aber unterschätzen sollten wir diese Schwachstelle nie.

Weitere Informationen

Zu diesem Thema habe ich ein Youtube-Clip erstellt:

Wer mehr über XSS lernen möchte: