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
- SQL Injection wordt gestopt doordat PDO Prepared Statements (
bindParam) worden gebruikt voor het opslaan. - 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
maxlengthaanpassen helpt niet: alle output is geëscaped doorhtmlspecialchars().
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.