Tutorials

Sessies en veiligheid

Sessies en veiligheid

Pagina 1

Veiligheid?! Pff… ik gebruik toch sessies!

Hehe, heb je eindelijk je user systeem met sessies af en denk je dat je lekker safe bent? Nou nee, integendeel zelfs! Zoals de meeste van jullie (hopelijk) weten wordt een sessie aan een gebruiker toegekend door middel van een session id. Deze 32 karakters tellende reeks wordt respectievelijk via een cookie of via de url doorgegeven aan de vervolg pagina’s. Als je hier eens goed over nadenkt, dan zal het je waarschijnlijk direct opvallen hoe eenvoudig het is om deze session id te manipuleren. Een ‘hacker’ hoeft slechts een aantal pogingen (oké… een aantal duizenden pogingen) te doen om een geldige id waarde te vinden. Tijd dus voor wat extra veiligheid…
Pagina 2

Superglobals

Voordat we beginnen met het ‘veiliger’ maken van sessies eerst nog even wat basic informatie over veiligheid. In PHP 4.2.0 werden voor het eerst de zogenaamde superglobals geïntroduceerd. Gelukkig heeft Mathieu hierover al een zeer duidelijk artikel geschreven, dat hier ook te lezen is. De reden dat ik dit onderwerp hierbij betrek is simpel, kijk maar eens naar het volgende voorbeeldje:

<?php

// start de sessie
session_start();

// controleer of de gebruiker ingelogd is
if ($login == 1)
{
// ingelogd!
}

?>

Zoals je ziet controleert dit ‘script’ of een gebruiker ingelogd is of niet. Dit gebeurt aan de hand van de sessie variabele $login, toch? Hoewel dit script voor een beginnende PHP’er misschien veilig lijkt zal het voor de iets meer gevorderden direct duidelijk zijn dat $login niet perse een sessie variabele hoeft te zijn. De check is namelijk zeer eenvoudig te omzeilen door het script aan te roepen via: script.php?login=1.

Lijkt me duidelijk, nietwaar? De oplossing is uiteraard net zo simpel als het voorbeeldje zelf. In plaats van het controleren van de variabelen $login, controleren we nu de ‘echte’ sessie variabele $login, door middel van de volgende code:

$_SESSION[‘login’] (of voor php < 4.2.0 HTTP_SESSION_VARS[])

Pagina 3

Het echte werk…

Het echte werk…
Nu de basic informatie over veiligheid weer vers in je geheugen zit, kunnen we verder gaan met het echte werk. De simpelste manier om ‘hackers’ (beter gezegd… scriptkiddies) tegen te houden is het opslaan van het ip adres in de sessie. In je script controleer je vervolgens of het IP in de sessie matcht met dat van de gebruiker. Komt het IP adres in de sessie niet overeen met dat van de gebruiker dan ‘destroy’ je (bijvoorbeeld) de sessie.

Opmerking: het idee achter sessies is dat ze beëindigd worden nadat een gebruiker het browser venster sluit. Als je een sessie langer wilt behouden dan kan het zijn dat een IP check niet altijd werkt. Sommige gebruiker met bijvoorbeeld inbelverbindingen, krijgen namelijk bij het inbellen steeds een ander IP toegewezen. Houd daar dus rekening mee!

Nog even een kort voorbeeldje:

<?
// start de sessie
session_start();

if (isset($_SESSION[‘login’]) && $_SESSION[‘ip’] == $_SERVER[‘REMOTE_ADDR’])
{
// ip matcht! gebruiker ingelogd!
}
else
{
session_destroy();
die(‘Hacking attempt!’);
}
?>
Pagina 4

Tot slot… de hash

Als laatste nog even een kleine aanvulling. Naast het stelen van de sessie id kan een meer ervaren ‘hacker’ ook sessies zelfs wijzigen. Uiteraard is ook de kans dat dit gebeurt zeer klein, maar neem het zekere voor het onzekere! Een mogelijke en simpele oplossing hiervoor is het genereren en opslaan van een hash. Een ‘hash’ is een soort van controle code voor bepaalde data waarmee eenvoudig vast te stellen is of data corrupt is of niet.

Het genereren van de hash:

<?
// start de sessie
session_start();

$sessdata_str = serialize($_SESSION);
$md5hash = md5($sessdata_str);

// opslaan van de hash
$_SESSION[‘hash’] = $md5hash;
?>

Simpel toch? Oh ja… bij het vergelijken van de hash met de sessie data moet je nog even opletten! Er is namelijk een variabele toegevoegd aan de sessie, die niet mee opgenomen is in de hash:

<?
// start de sessie
session_start();

// ip check en overige dingen..

$sessdata = $_SESSION;
unset($sessdata[‘hash’]);

sessdata_str = serialize($sessdata);
$md5hash = md5($sessdata_str);

// controleren van de hash
if ($_SESSION[‘hash’] == $md5hash)
{
// hash komt overeen! Sessie is geldig!!
}
?>

Tot slot dus dit voorbeeldje. Uiteraard zijn er nog talloze andere manieren om sessie nog veiliger te maken, dus mis je hier nog iets dan hoor ik dit graag! Succes met PHP verder!

Daniel Bakker.

Reacties

0
Nog geen reacties.