Zwei der ältesten und zugleich hartnäckigsten Schwachstellen im Web tragen die Kürzel XSS und CSRF. Beide tauchen seit Jahren in nahezu jeder Liste der häufigsten Webrisiken auf, beide werden regelmäßig unterschätzt, und beide lassen sich mit überschaubarem Aufwand wirksam eindämmen. Der Haken: Es handelt sich um zwei grundverschiedene Angriffsarten, die unterschiedliche Schutzmaßnahmen verlangen. Wer nur an eine denkt, lässt eine offene Flanke. Dieser Ratgeber erklärt verständlich, wie Cross-Site-Scripting und Cross-Site-Request-Forgery funktionieren, worin sie sich unterscheiden und welche Gegenmaßnahmen in der Praxis tatsächlich greifen.
Was ist Cross-Site-Scripting (XSS)?
Bei XSS gelingt es einem Angreifer, eigenen JavaScript-Code in eine vertrauenswürdige Seite einzuschleusen, sodass dieser Code im Browser anderer Besucher ausgeführt wird. Die Seite vertraut dem Skript, weil es scheinbar von ihr selbst stammt. Dadurch kann der Code alles tun, was auch die echte Seite dürfte: Sitzungs-Cookies auslesen, Formulare manipulieren, Tastatureingaben mitschneiden oder Inhalte austauschen.
Die typische Ursache ist, dass eine Anwendung Benutzereingaben ungefiltert wieder in die Seite schreibt. Ein Kommentarfeld, ein Suchformular, ein Profilname – überall dort, wo Text aus einer Eingabe später im HTML landet, kann Schadcode mitreisen, wenn die Ausgabe nicht korrekt behandelt wird. Man unterscheidet grob drei Varianten:
- Persistentes (gespeichertes) XSS: Der Schadcode wird in der Datenbank abgelegt, etwa in einem Kommentar, und bei jedem Aufruf erneut ausgeliefert. Besonders gefährlich, weil viele Besucher betroffen sind.
- Reflektiertes XSS: Der Code steckt in einem Link oder einer Anfrage und wird sofort in die Antwort zurückgespiegelt. Das Opfer muss dazu auf einen präparierten Link klicken.
- DOM-basiertes XSS: Die Schwachstelle liegt im clientseitigen JavaScript selbst, das unsichere Werte direkt ins Dokument schreibt, ohne dass der Server beteiligt ist.
Wirksamer Schutz gegen XSS
Die wichtigste Verteidigung ist konsequentes Output-Escaping: Bevor ein Wert in HTML ausgegeben wird, werden Sonderzeichen wie spitze Klammern und Anführungszeichen in ihre harmlosen Entity-Schreibweisen umgewandelt. So wird aus einem Skript-Tag nur sichtbarer Text statt ausführbarer Code. Entscheidend ist, je nach Kontext richtig zu escapen – HTML-Kontext, Attribut-Kontext, JavaScript-Kontext und URL-Kontext erfordern unterschiedliche Behandlung. Moderne Template-Engines escapen Ausgaben standardmäßig; man sollte diesen Schutz nur in begründeten Ausnahmen abschalten.
Als zweite Verteidigungslinie dient die Content-Security-Policy (CSP). Über einen HTTP-Header legt die Seite fest, aus welchen Quellen Skripte geladen werden dürfen, und kann Inline-Skripte komplett verbieten. Selbst wenn Schadcode durchrutscht, wird seine Ausführung dann vom Browser blockiert. Weitere sinnvolle Bausteine:
- Cookies mit dem
HttpOnly-Flag versehen, damit JavaScript nicht auf sie zugreifen kann. - Beim Einfügen von Inhalten ins DOM
textContentstattinnerHTMLverwenden. - Wenn HTML aus Nutzereingaben erlaubt sein muss, eine bewährte Sanitizer-Bibliothek einsetzen statt selbst zu filtern.
Was ist Cross-Site-Request-Forgery (CSRF)?
CSRF setzt an einer anderen Stelle an. Hier wird kein Code eingeschleust, sondern eine bestehende, gültige Anmeldung des Opfers missbraucht. Ist ein Nutzer bei einer Seite eingeloggt, schickt der Browser deren Cookies bei jeder Anfrage automatisch mit – auch dann, wenn die Anfrage von einer fremden Seite ausgelöst wurde. Genau das nutzt CSRF aus.
Ein Angreifer bringt das Opfer dazu, eine präparierte Seite zu besuchen. Diese löst im Hintergrund eine Aktion auf der eigentlichen Zielseite aus, etwa eine Passwortänderung, eine Überweisung oder das Löschen eines Kontos. Weil die gültigen Cookies mitgesendet werden, hält der Server die Anfrage für legitim. Das Opfer bemerkt davon oft nichts. CSRF zielt also nicht darauf, Daten zu lesen, sondern zustandsändernde Aktionen unbemerkt auszulösen.
Wirksamer Schutz gegen CSRF
Das Standardmittel ist das CSRF-Token: ein zufälliger, nur dem Server und der echten Seite bekannter Wert, der in jedes Formular eingebettet wird. Bei jeder zustandsändernden Anfrage prüft der Server, ob das mitgesendete Token gültig ist. Eine fremde Seite kennt diesen Wert nicht und kann ihn nicht erraten, ihre gefälschten Anfragen werden also abgewiesen. Viele Frameworks erzeugen und prüfen diese Token automatisch, sofern man die vorgesehenen Formular-Helfer nutzt.
Eine zweite, sehr effektive Schutzschicht sind SameSite-Cookies. Mit dem Attribut SameSite=Lax oder SameSite=Strict weist man den Browser an, das Cookie bei seitenübergreifenden Anfragen nicht oder nur eingeschränkt mitzusenden. Damit verliert ein klassischer CSRF-Angriff seine Grundlage. Ergänzend gilt:
- Zustandsändernde Aktionen ausschließlich über POST, PUT, PATCH oder DELETE abwickeln, niemals über GET.
- Bei besonders sensiblen Vorgängen zusätzlich das aktuelle Passwort oder eine zweite Bestätigung verlangen.
- Den
Origin- beziehungsweiseReferer-Header serverseitig prüfen, wo verfügbar.
XSS und CSRF im direkten Vergleich
Beide Angriffe brauchen unterschiedliche Antworten, weil sie an verschiedenen Stellen ansetzen. Die folgende Übersicht stellt Angriffsprinzip, Voraussetzung und die wichtigsten Schutzmaßnahmen gegenüber.
| Merkmal | XSS (Cross-Site-Scripting) | CSRF (Cross-Site-Request-Forgery) |
|---|---|---|
| Angriffsprinzip | Fremder Skriptcode wird in die Seite eingeschleust und im Browser des Opfers ausgeführt | Eine gefälschte Anfrage nutzt die bestehende Anmeldung des Opfers |
| Voraussetzung | Ungefilterte Ausgabe von Benutzereingaben | Aktive, eingeloggte Sitzung und automatisch mitgesendete Cookies |
| Ziel des Angriffs | Daten stehlen, Sitzungen kapern, Seiteninhalte manipulieren | Zustandsändernde Aktion unbemerkt auslösen |
| Wichtigster Schutz | Output-Escaping je Kontext, Content-Security-Policy | CSRF-Token, SameSite-Cookies |
| Ergänzende Maßnahmen | HttpOnly-Cookies, Sanitizer, textContent statt innerHTML | Sichere HTTP-Methoden, Origin-Prüfung, Re-Authentifizierung |
Warum man immer serverseitig validiert
Eine verbreitete Fehlannahme lautet, Prüfungen im Browser reichten aus. Tatsächlich lässt sich jede clientseitige Validierung umgehen, da der Angreifer die Anfrage direkt an den Server schicken kann, ganz ohne die echte Oberfläche. JavaScript im Browser dient der Benutzerfreundlichkeit, nicht der Sicherheit. Verbindlich ist allein die Prüfung auf dem Server. Dort müssen Eingaben gegen erwartete Formate, Längen und Wertebereiche geprüft und vor der Weiterverarbeitung sauber behandelt werden. Erst die Kombination aus serverseitiger Validierung und kontextrichtigem Escaping bei der Ausgabe ergibt einen belastbaren Schutz.
Warum beide Maßnahmen nötig sind
XSS und CSRF schließen sich nicht aus, sie ergänzen sich. Ein CSRF-Token schützt nicht vor eingeschleustem Skriptcode, und Output-Escaping verhindert keine gefälschten Anfragen aus einer gültigen Sitzung. Schlimmer noch: Eine XSS-Lücke kann CSRF-Schutz aushebeln, weil bösartiger Code das gültige Token direkt von der Seite auslesen und mitschicken kann. Sicherheit im Web folgt deshalb dem Prinzip mehrerer Schichten. Wer Eingaben validiert, Ausgaben escapt, eine CSP setzt, Token einsetzt und Cookies mit den richtigen Flags ausstattet, macht es Angreifern an jeder einzelnen Stelle deutlich schwerer.
Eine kurze Routine für die Praxis:
- Alle Eingaben serverseitig prüfen und auf erwartete Formate begrenzen.
- Jede Ausgabe kontextgerecht escapen, Standard-Escaping nicht abschalten.
- Eine restriktive Content-Security-Policy aktivieren und schrittweise verfeinern.
- CSRF-Token für alle zustandsändernden Formulare einsetzen.
- Cookies mit HttpOnly, Secure und einem passenden SameSite-Wert versehen.
Häufige Fragen
Was ist der wichtigste Unterschied zwischen XSS und CSRF?
XSS schleust fremden Code in eine Seite ein, der dann im Browser des Opfers läuft. CSRF schleust keinen Code ein, sondern missbraucht eine bereits bestehende Anmeldung, um in deren Namen Aktionen auszulösen. XSS zielt eher auf Datendiebstahl, CSRF auf das unbemerkte Auslösen von Aktionen.
Reicht ein CSRF-Token allein für die Sicherheit?
Nein. Ein CSRF-Token schützt nur vor gefälschten Anfragen. Gegen eingeschleusten Skriptcode hilft es nicht. Besteht zugleich eine XSS-Lücke, kann der Schadcode das Token sogar selbst auslesen. Man braucht beide Schutzrichtungen gemeinsam.
Was bewirkt das SameSite-Attribut bei Cookies?
Es steuert, ob ein Cookie bei seitenübergreifenden Anfragen mitgesendet wird. Mit Strict oder Lax sendet der Browser das Cookie bei Anfragen von fremden Seiten nicht oder nur eingeschränkt mit und entzieht klassischen CSRF-Angriffen damit die Grundlage.
Genügt es, Eingaben im Browser zu prüfen?
Nein. Clientseitige Prüfungen lassen sich umgehen, weil eine Anfrage direkt an den Server gesendet werden kann. Sicherheitsrelevant ist ausschließlich die Validierung auf dem Server. JavaScript-Prüfungen verbessern nur den Komfort.
Was leistet eine Content-Security-Policy?
Eine CSP legt per HTTP-Header fest, aus welchen Quellen Skripte und andere Ressourcen geladen werden dürfen, und kann Inline-Skripte unterbinden. Sie dient als zweite Verteidigungslinie: Selbst wenn Schadcode in die Seite gelangt, wird seine Ausführung vom Browser blockiert.
Sind XSS und CSRF heute noch relevant?
Ja. Trotz besserer Frameworks und Standardabwehr gehören beide weiterhin zu den am häufigsten gemeldeten Webschwachstellen. Sie entstehen meist durch Flüchtigkeitsfehler oder abgeschalteten Standardschutz, weshalb regelmäßige Aufmerksamkeit nötig bleibt.
Weitere praxisnahe Beiträge findest du in unseren News. Nützliche Helfer für den Entwickleralltag bündelt unsere Webtools-Sammlung, und einen Gesamtüberblick gibt die Startseite.