Un serveur web peut avoir un comportement étrange même si tout semble bien conçu. En effet, la gestion des sessions (qui n’est pas vraiment le point fort du protocole HTTP) peut s’avérer délicat et peut entraîner des problèmes de type fixation de session.
Marquons la session
Il est assez courant de voir qu’un identifiant unique et impossible à deviner soit associé à une session particulière d’un utilisateur. Pour se connecter, il faut en général que l’utilisateur s’authentifie avec ce numéro de session unique, attribué par le serveur web. Donc a priori aucune chance qu’un attaquant externe arrive connecter sans connaître les crédentités de l’utilisateur.
Demandons poliment à l’utilisateur de le faire pour nous
Qu’à cela ne tienne : demandons alors à l’utilisateur légitime de s’authentifier à notre place (si on est l’attaquant). Comment ? D’abord en s’attribuant un numéro de session. Pour cela, il suffit d’aller sur le site ciblé. Si cet identifiant est inséré dans l’URL, on obtiendra alors quelque chose qui ressemble à ça :
https://lebeausitevisé.com/accueil?app_session_id=1c9d5e00dcbc3c77e55798b74c5267f
Vous devinez la suite ? Le méchant va envoyer un gentil mail à la victime en prétextant une mise à jour des fonctionnalités, une vérification de sécurité ou n’importe quoi d’autre en lui demandant de cliquer sur cette URL bien précise. Si la victime clique et que le serveur web ne prend pas les précautions adaptées, elle ira sur le site, où on lui redemandera se s’authentifier et le tour est joué : cette session sera considérée comme valide et authentifiée ! Il ne reste plus à l’attaquant à rafraîchir sa fenêtre (avec la même URL et donc le même numéro de session et il se retrouvera connecté avec l’identité de la victime, sans aucune manipulation complexe (tel qu’un vol de cookie).
Contre-mesures
Il y a plusieurs façons d’atténuer le risque. On peut :
- Modifier le numéro de session une fois l’authentification réalisée. Ainsi l’attaquant ne pourra pas profiter de la connaissance de cet identifiant impossible à deviner en théorie.
- Ne pas utiliser d’identifiant de session dans les requêtes GET ou POST et le stocker dans un cookie.
- Utiliser des identifiants de session non prévisibles et contrôlés uniquement par le serveur, ce qui implique (entre autres) l’utilisation d’un bon générateur de nombres aléatoires !
En Python, avec Django, cela peut donner :
request.session.flush()
request.session.cycle_key()
Voir aussi