XSS-injection
PHP is dynamisch en er wordt vaak met een database gewerkt. Maar net zoals in de vorige pagina, waarbij we pagina naar de database stuurden, is het beveiligen van het ophalen van data uit de database net zo belangrijk. (gedetailleerde uitleg: klik hier)
Wat is XSS-injection?
XSS staat voor Cross-site scripting. XSS-injection betekent dat gebruikers hun eigen code in de HTML kunnen injecteren. Dat kan ertoe leiden dat er bijvoorbeeld cookies van administrators, die belangrijke informatie bevatten, uitgelezen kunnen worden. Dat is natuurlijk iets wat je wilt voorkomen.
Hoe werkt XSS-injection?
Wanneer er op een pagina dynamische content (bijvoorbeeld dat van een gebruiker) getoond wordt, is het belangrijk dat dit geen HTML-code kan zijn. Als dit wel het geval is, dan kan de gebruiker HTML-code invoegen, en dat is niet de bedoeling.
We gebruiken als voorbeeld een klein formulier waarbij de gebruiker zijn naam en leeftijd moet opgeven. Als hij één van de twee velden niet invult, dan moet hij het formulier opnieuw invullen en wordt het veld dat wél was ingevuld, opnieuw gevuld met hetgeen dat hij daarvoor ingevuld had.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Kijken of er gepost is
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
// Controleren of beide velden ingevuld zijn
if (empty($_POST['bericht']) || empty($_POST['leeftijd']))
{
echo 'Je hebt niet beide velden ingevuld!';
}
else
{
// Hier de verdere verwerking van het formulier
}
}
// Form op het scherm tonen
?>
<form method="post" action=""><p>
Naam: <input type="text" name="naam" value="<?php echo (isset($_POST['naam']) ? $_POST['naam'] : ''); ?>" /><br />
Leeftijd: <input type="text" name="leeftijd" value="<?php echo (isset($_POST['leeftijd']) ? $_POST['leeftijd'] : ''); ?>" /><br />
<input type="submit" value="Versturen" />
</p></form>
Ook hier lijkt er op het eerste gezicht niet veel fout te zijn aan de code. Alleen op regel achttien en negentien zit toch wel degelijk een fout. Je ziet het misschien niet goed, maar de post-waarde van 'naam' en 'leeftijd' wordt op het scherm getoond. En dit wordt niet speciaal aangepast, maar het wordt gewoon precies zoals ingetypt in de broncode gezet.
Stel dat iemand bijvoorbeeld invult Kees"/> - wat gebeurt er dan? Dan plaatst PHP dat stuk PRECIES tussen de value tags en krijg je gewoon dit in je broncode:
<input type="text" name="naam" value="Kees" />" />
Hoe kan dit?
Omdat je PHP de instructie geeft de input van de gebruiker daar op het scherm te tonen, zal PHP dit ook zo doen. Je ziet dus dat het tekstvak afgesloten wordt op basis van de input van de gebruiker. Daarom is het belangrijk om gebruiker input altijd te filteren voordat je het op het scherm toont!
Hoe doe je dit?
Dat is erg simpel, je gebruikt gewoon de htmlspecialchars functie van PHP. Deze zet "vreemde" tekens om naar tekens die ongevaarlijk zijn voor de broncode.
Voorbeeld in de praktijk
2
3
4
5
Naam: <input type="text" name="naam" value="<?php echo (isset($_POST['naam']) ? htmlspecialchars($_POST['naam']) : ''); ?>" /><br />
Leeftijd: <input type="text" name="leeftijd" value="<?php echo (isset($_POST['leeftijd']) ? htmlspecialchars($_POST['leeftijd']) : ''); ?>" /><br />
<input type="submit" value="Versturen" />
</p></form>
Wat gebeurt er nu?
De "vreemde" tekens (zoals quotes en kleiner-dan en groter-dan tekens) worden dan omgezet naar HTML codes die de browser niet parsed. Dat klinkt misschien ingewikkeld, maar eigenlijk is dat helemaal niet zo. Wanneer je nu Kees" /> invult, dan krijg je deze output, die ongevaarlijk is:
<input type="text" name="naam" value="Kees\" />" />
Zoals je ziet wordt hier het 'value' attribuut niet afgesloten door de input van de gebruiker.
Ook hier weer geen ernstige fout die je kunt misbruiken, maar dit is zowat het simpelste misbruik van XSS-injectie.
Referenties
Inhoudsopgave
- Leesbaarheid
- SQL-injection
- XSS-injection
- Gebruik van backticks in MySQL
- Correcte foutenafhandeling
- Geheugenefficiënt programmeren
- Slot