MB Dev .tech
Registrieren Login

Sicherheit Basics · XSS & Escaping

← Zurück zu Sicherheit Basics

XSS steht für Cross-Site Scripting. Das passiert, wenn ein Angreifer es schafft, dass fremder JavaScript-Code in deiner Seite ausgeführt wird – meist über Benutzereingaben, die du später wieder ausgibst.

Achtung
Das Risiko entsteht fast immer bei der Ausgabe

Du kannst Eingaben validieren – aber der wichtigste Schutz gegen XSS ist: Output Escaping im richtigen Kontext.

1) XSS in einfachen Worten

Stell dir vor, deine Seite zeigt Kommentare an. Ein Nutzer kann einen Text schreiben – und du gibst diesen Text später auf der Webseite aus.

Wenn du den Text einfach „roh“ ausgibst, kann jemand statt einem Kommentar auch HTML/JavaScript einschleusen. Dann wird das nicht nur angezeigt – es kann im Browser laufen.

Merke
XSS ist „Code in der Seite“ statt „Text in der Seite“

Du willst, dass Benutzereingaben als Text erscheinen – nicht als ausführbarer Code.

2) Unsicher vs. sicher: Ausgabe im HTML-Kontext

Hier ist der Klassiker: eine Variable wird in HTML ausgegeben. Ohne Escaping kann sie HTML „brechen“.

Unsicher (nicht nachmachen)

$comment = $_POST['comment'] ?? '';

echo "<p>" . $comment . "</p>";

Sicherer ist: Du wandelst Sonderzeichen um, damit sie nicht als HTML interpretiert werden.

Sicher (HTML escapen)

$comment = $_POST['comment'] ?? '';

$safe = htmlspecialchars($comment, ENT_QUOTES, 'UTF-8');

echo "<p>" . $safe . "</p>";
Tipp
ENT_QUOTES ist wichtig

Damit werden auch Anführungszeichen sicher umgewandelt. Das hilft besonders bei HTML-Attributen.

3) Der wichtigste Punkt: Kontext entscheidet, wie du escapst

„Escaping“ ist kein einzelner Trick. Du musst wissen, wo die Ausgabe landet:

  • HTML-Text: innerhalb von <p>...</p>
  • HTML-Attribut: z.B. value="..."
  • URL: z.B. href="..."
  • JavaScript: z.B. in einem Script-Block
Achtung
HTML-Escaping ist nicht automatisch JS-Escaping

Viele XSS-Bugs entstehen, weil etwas „irgendwie escaped“ wurde, aber im falschen Kontext.

4) Beispiel: Ausgabe in einem HTML-Attribut

Ein typischer Fall ist ein Formularfeld, das einen Wert wieder anzeigt: z.B. nach einem Validierungsfehler.

Attribut-Ausgabe (sicher)

$name = $_POST['name'] ?? '';

$safeName = htmlspecialchars($name, ENT_QUOTES, 'UTF-8');

echo '<input type="text" name="name" value="' . $safeName . '">';
Merke
Formulare sind XSS-Hotspots

Weil du Eingaben oft wieder zurück ins HTML schreibst. Genau dort ist Escaping Pflicht.

5) Reflected XSS vs. Stored XSS

Es gibt zwei häufige Varianten:

  • Reflected XSS: Code kommt über URL/Formular und wird sofort angezeigt.
  • Stored XSS: Code wird gespeichert (z.B. Kommentar) und später anderen angezeigt.
Achtung
Stored XSS ist oft gefährlicher

Weil es nicht nur den „Angreifer“ betrifft, sondern alle, die die Seite später besuchen.

6) Praktische Regeln für den Alltag

  • Alles, was von außen kommt, ist „untrusted“ (Form, URL, DB kann auch „vergiftet“ sein).
  • Beim Ausgeben: immer escapen (HTML-Kontext: htmlspecialchars).
  • Keine Benutzereingabe direkt in <script> oder JS-Strings schreiben.
  • Wenn du HTML aus Benutzereingaben erlauben willst: dann brauchst du Whitelists/Sanitizer.
Tipp
„Escape late“

Speichere Daten möglichst „roh“ (z.B. Kommentartext) und escape erst beim Ausgeben. Dann bist du flexibel, wo du es später anzeigen willst.

Kleine Aufgaben (zum Mitdenken)

Aufgabe 1: Was ist hier das Problem?
Aufgabe

$title = $_GET['title'] ?? '';
echo "<h1>" . $title . "</h1>";
Lösung einblenden
Lösung
Unescaped Output → XSS-Risiko

$title wird direkt ins HTML geschrieben. Richtig wäre: htmlspecialchars($title, ENT_QUOTES, 'UTF-8').