Ga naar hoofdinhoud

XSS (Stored) — Impossible

Tijd om te leren hoe we gastenboeken écht veilig bouwen.

1. Predict (Voorspel)

De onveilige functies zijn vervangen door de zwaarste geschut in PHP:

$message = htmlspecialchars( $_POST['txtMessage'] );
$name = htmlspecialchars( $_POST['txtName'] );

$stmt = $db->prepare('INSERT INTO guestbook (comment, name) VALUES (:message, :name)');
$stmt->bindParam(':message', $message, PDO::PARAM_STR);

Vraag: Welke twee bekende kwetsbaarheden worden in deze code tegelijkertijd dichtgetimmerd?

Antwoord
  1. SQL Injection wordt gestopt doordat PDO Prepared Statements (bindParam) worden gebruikt voor het opslaan.
  2. Cross-Site Scripting (XSS) wordt gestopt doordat álle invoer door htmlspecialchars() wordt gehaald. Eventuele < en > tekens worden geneutraliseerd tot onschuldige tekst.

2. Run & Investigate

Start het lab.

Laden...

Probeer via F12, scripts en afbeeldingen de website te hacken. Alles wat je typt zal braaf als tekst in het gastenboek verschijnen.

3. ✓ Wat moest je zien?

Controle
  • Welke payload je ook intypt: geen popup, geen verstoring van de pagina.
  • In het gastenboek verschijnt je payload letterlijk als tekst, met < en > zichtbaar.
  • F12 ontwijken via maxlength aanpassen helpt niet: alle output is geëscaped door htmlspecialchars().

Krijg je tóch een popup? Dan staat het level rechtsboven niet op Impossible — of de gastenboekdatabase bevat nog payloads van eerdere levels (Reset DB via Setup).

Wat heb je geleerd?

  • Stored XSS is gevaarlijker dan Reflected XSS, omdat de payload in de database leeft. Je raakt niet 1 persoon met een foute link, maar iedereen die de website bezoekt.
  • Client-Side restricties (zoals maxlength) zijn een lachertje. Een hacker trekt zich daar niets van aan. Bouw áltijd validatie in je backend.
  • De combinatie van Prepared Statements en htmlspecialchars (of soortgelijke functies in andere talen) is de heilige graal voor veilige formulieren.