IV. Protection contre le vol de session▲
IV-A. Identification par l'environnement▲
IV-A-1. L'adresse IP▲
Pour éviter le vol de session, l'enregistrement de l'adresse IP apparaît comme une solution évidente. En effet, une machine -> une session -> un utilisateur. Si l'IP change, cela signifie que la session a été volée et utilisée sur une autre machine. Pour réaliser ce contrôle, c'est très simple, une fonction de ce type retourne l'IP de l'utilisateur.
/**
*
@desc
Récupére
l
'
adresse
IP
du
client
*
@return
string
*
@access
public
*/
public function getIP()
{
if(getenv('
HTTP_X_FORWARDED_FOR
'
))
{
return getenv('
HTTP_X_FORWARDED_FOR
'
);
}
elseif(getenv('
HTTP_CLIENT_IP
'
))
{
return getenv('
HTTP_CLIENT_IP
'
);
}
else
{
return getenv('
REMOTE_ADDR
'
);
}
}
En théorie, c'est parfait.
En pratique, cette méthode est pour moi inutile et même parfois embêtante, d'une part l'IP n'est pas une valeur sûre, d'autre part l'IP d'un même utilisateur peut changer au cours du temps.
Session Hijacking et IP spoofing
Je ne m'attarderai pas trop sur ces notions, il y a juste besoin de savoir qu'une IP, ça se vole. Pour en savoir plus, vous pouvez aller voir les articles de David Burgermeister et Jonathan Krier ( ici ).
IP instable
Certains fournisseur comme AOL et certaines entreprises ou universités renouvellent très souvent l'IP de leurs ordinateurs, rendant impossible l'existence d'une session se reposant dessus.
Fonder son authentification sur l'IP revient à renoncer à beaucoup d'utilisateurs potentiels.
IV-A-2. Variable d'environnement▲
Une autre méthode pour avoir une "signature" d'un visiteur est d'utiliser son environnement, c'est-à-dire son explorateur, son système d'exploitation, etc.
On est sûr que ces données ne changeront pas pendant la session.
Par contre, comme l'IP, c'est loin d'être involable. En fait, c'est même inutile car si le hacker a déjà volé l'identifiant de session par l'écoute du réseau, il aura aussi capturé ceci :
IV-A-3. Conclusion▲
En conclusion, se fier à des données liées à un utilisateur pour fiabiliser la session n'est pas une bonne idée, car ces données proviennent justement de l'utilisateur ;-) et la première règle en développement d'application web est de ne jamais faire confiance à ce qui vient de l'extérieur, adresse IP comprise.
Il faut évidemment relativiser, le vol d'adresse IP n'est pas donné à tout le monde, mais je déconseille malgré tout cette technique à cause de l'instabilité de l'IP.
Le meilleur moyen de protéger sa session d'un vol est de chiffrer la session entière grâce au SSL que nous allons voir un peu plus loin.
IV-B. Système de ticket▲
Un hacker qui vole une session signifie que l'utilisateur réel est lui aussi connecté sur le site, sinon il n'y aurait pas de session. Ce hacker volera une seule fois l'identifiant de session, puis l'utilisera.
En somme, il y a 2 utilisateurs sur le même compte.
L'idée est de donner un ticket à l'utilisateur qui demande une page. Pour obtenir la suivante, il faudra renvoyer ce ticket. Si celui-ci ne correspond pas, la session est annulée; si il correspond, un nouveau ticket est délivré.
Ainsi, voici le déroulement lors d'un vol de session
- Le visiteur demande une page
- On génère un ticket (exemple : toto123), on le mémorise coté serveur et on l'envoie coté client.
- L'utilisateur demande une nouvelle page
- On récupère le numéro du ticket coté client, on le compare avec celui en mémoire côté serveur
- Le numéro correspond, on envoie la page et on renouvelle le ticket (exemple : titi456)
- Le hacker demande ensuite la page (il connaît l'identifiant de session et possède un ticket qui lui est propre)
- Le ticket du hacker ne correspond pas avec celui de l'utilisateur, on coupe la session
En pratique, il suffit de créer un cookie que l'on renouvelle à chaque page, on le stocke aussi en session.
$ticket
=
uniqid(strval(mt_rand() (1,
999999)));
$_COOKIE
[
'
ticket
'
]
=
$ticket
;
$_SESSION
[
'
ticket
'
]
=
$ticket
;
Lors de l'appel d'une nouvelle page, on vérifie.
if ($_COOKIE
[
'
ticket
'
]
=
=
$_SESSION
[
'
ticket
'
]
)
{
//
On
renouvelle
$ticket
=
uniqid(strval(mt_rand() (1,
999999)));
$_COOKIE
[
'
ticket
'
]
=
$ticket
;
$_SESSION
[
'
ticket
'
]
=
$ticket
;
}
else
{
//
On
DECONNECT
}
Cette technique présente tout de même une grosse faiblesse. Si le hacker vole la session alors que l'utilisateur vient de terminer sans se déconnecter, le hacker réussira.
En effet, le hacker vole l'identifiant de session et le ticket délivré au membre lorsque celui-ci appelle la dernière page, le hacker les utilise ensuite comme les siens. Pour le serveur, il n'y a aucun moyen de voir la permutation, vu qu'il ne voit qu'un seul utilisateur tout le long.
Il faut forcer du mieux possible l'utilisateur à se déconnecter manuellement après chaque session.
Vous vous dites peut-être que vous avez déjà vu l'idée quelque part.
En effet, PHP définit la fonction session_regenerate_id( ).
Cette fonction fait globalement la même chose que notre système de ticket, à la différence (énorme) que l'ancienne session n'est pas effacée et qu'elle ne s'applique pas à un ticket arbitraire mais à l'identifiant de session. Ainsi, chaque appel à session_regenerate_id ajoute une nouvelle session et augmente les chances de se faire voler une de ses sessions.
Heureusement, depuis PHP 5.1.0, cette fonction prend le paramètre facultatif [bool delete_old_session]. Mais attention, celui-ci est à false par défaut.