Helaas, door een cross site scripting probleem op je favoriete website heeft een hacker je session cookie bemachtigd, ga niet langs start. De hacker heeft ondertussen toegang tot jouw sessie op de website, en daar gaat al je e-mail, je vriendjes of je matches. Ok, cross site scripting hoort niet voor te komen, maar een meerlaags security model had dit kunnen opvangen. Jammer dat PHP (en andere web programmeertalen) de sessies niet veilig implementeren. Hoogste tijd om het zelf te doen.
Omdat een webpagina eigenlijk stateless is, wordt tegenwoordig altijd een cookie gebruikt met hierin een sessionid. Dit id is uniek voor de sessie die jij met de website hebt, en geeft de server de mogelijkheid om informatie van jouw sessie bij te houden. Na het inloggen met gebruikersnaam Piet weet de server bijvoorbeeld dat de sessie met jouw sessionid is ingelogd als gebruiker Piet.
Hackers kunnen jouw sessionid op twee manieren bemachtigen. De eerste heet session-fixation, waarbij de hacker vooraf een sessionid bepaalt, en jou deze laat gebruiken. De tweede heet session-hijacking, waarbij de hacker je sessionid kaapt met behulp van cross site scripting. Mocht je meer willen weten over deze twee aanvallen, zoek dan op de termen 'session fixation', 'cross site scripting', 'session hijacking', dit artikel gaat juist over de beveiliging van de sessies.
Voor veilige sessies in PHP zul je zelf wat moeten programmeren. Als het goed is heb je al in een initialisatiescript een aanroep van session_start() staan. Er bestaan in PHP een paar functies om wat parameters van het session cookie aan te passen:
void session_set_cookie_params ( int lifetime
[, string path [,string domain [, bool secure
[, bool httponly]]]] )
string session_name ( [string name] )
session_name($cookiename);
session_set_cookie_params(0,
"/~test/cs/test.php", "127.0.0.1",
true, true);
if (!$_SERVER['SSL_PROTOCOL']) {
header("Location: https://127.0.0.1/~test/cs/test.php");
exit;
}
if (!$_SESSION || $_SESSION['initialized'] !== true) {
session_regenerate_id(true);
$_SESSION['initialized'] = true;
}
De complete implementatie in een mooi direct bruikbare functie, inclusief ip-adres is als volgt:
function securesession
($path, $domain, $cookiename, $secureurl) {
/* Force the usage of SSL */
if (!$_SERVER['SSL_PROTOCOL']) {
header("Location: $secureurl");
exit;
}
/* Set correct sessioncookie parameters */
session_name($cookiename);
session_set_cookie_params(0, $path, $domain, true, true);
session_start();
/* Test for a proxy */
$forward = "";
if (defined($_SERVER['REMOTE_ADDR'])) {
$forward = $_SERVER['REMOTE_ADDR'];
}
/* Force the creation of a sessionid */
if (!$_SESSION || $_SESSION['initialized'] !== true) {
session_regenerate_id(true);
$_SESSION['initialized'] = true;
$_SESSION['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
$_SESSION['X_FORWARDED_FOR'] = $forward;
}
/* Test the user's ip and possible proxy */
if (($_SERVER['REMOTE_ADDR'] != $_SESSION['REMOTE_ADDR']) ||
($_SESSION['X_FORWARDED_FOR'] != $forward)) {;
$_SESSION = array();
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '',
time()-42000, $path,
$domain, false, true);
}
session_destroy();
exit();
}
securesession("/~test/cs",
"127.0.0.1", "TESTID",
"https://127.0.0.1/~test/cs/test.php");
print "Welcome";
?>
Deze posting is gelocked. Reageren is niet meer mogelijk.