- par
- Watilin
- le
- 01/10/2014 à 13:46
- catégorie
- Informatique
Quelques mots sur les cookies
Aujourd’hui, je voulais vous parlez de deux-trois trucs que j’ai remarqués à propos des cookies, et de leur manipulation en JavaScript. Il n’y a pas vraiment de lien entre ces différents points, alors ça va être un peu en vrac. Si ça vous plaît pas, allez vous brosser.
De la sécurité des cookies de session
Le cookie de session, les développeurs web le connaissent bien : il se nomme souvent SID
ou PHPSESSID
. En PHP, c’est celui qui est utilisé par la fonction session_start()
. C’est un cookie qui est généré par le serveur, et stocke un identifiant de session sous la forme d’une chaîne de caractères assez longue (par exemple 3e3eccfc9d9de05212dc4ac9f57fafb9
). Cet identifiant permet d’associer le visiteur avec un bloc de données stockées sur le serveur : les données de session du visiteur.
Bon, j’ai parlé un peu vite : le cookie de session ne permet pas exactement d'identifier le visiteur. En réalité, il identifie le navigateur du visiteur, car c’est le navigateur qui génère des requêtes HTTP, dans lesquelles se trouvent les cookies. En théorie, un seul navigateur connaît l’identifiant de session, car le serveur ne le transmet qu’une seule fois (à la création de la session).
Mais que se passe-t-il si un pirate (ou pire, une administration) écoute le réseau ? Le sniffing est un danger constant, en particulier avec le Wifi. Une personne qui lit les paquets HTTP envoyés par votre navigateur verra vos cookies, et connaîtra votre identifiant de session. Il lui suffit alors de reconstruire le cookie sur son propre navigateur, et de s’adresser au même serveur : il utilisera votre session.
Des solutions
Se déconnecter…
Pour réduire les risques, il y a une bonne habitude à prendre en tant que visiteur : quand vous avez fini d'utiliser un site (exemple au hasard : Facebook), déconnectez-vous. Ceci provoque la destruction de la session : les données stockées sur le serveur sont supprimées (en PHP, la fonction session_destroy()
permet de faire ça). Ainsi, le cookie de session ne sert plus à rien puisque la session à laquelle il correspond a été détruite. Si un usurpateur utilisait votre session au moment où vous vous êtes déconnecté, il sera déconnecté également.
Observer l’adresse IP ?
Du point de vue administrateur, on pourrait imaginer une solution basée sur l’adresse IP, facile à mettre en œuvre : à la création de la session, on stocke l’adresse IP ; ensuite, à chaque requête avec le même identifiant, on vérifie que l’IP est la même.
Cette solution n’est pas envisageable à cause des IP dynamiques, et des réseaux d’entreprise utilisant des passerelles à IP tournantes. Si l’administrateur d’un site adoptait cette solution, il rendrait son site inutilisable pour une partie non négligeable de ses utilisateurs…
Chiffrer !
La meilleure solution actuellement, c’est le protocole HTTPS
. Lors d’une connexion HTTPS, le navigateur et le serveur chiffrent toutes les données qu’ils transmettent. Les algorithmes de chiffrage actuels sont suffisamment efficaces pour protéger vos données jusqu’à ce que la vie sur Terre ne soit plus possible. Le cookie de session étant chiffré comme le reste, il n’est plus possible de le récupérer par sniffing : la session est protégée.
Malheureusement, pour offrir à ses visteurs une connexion HTTPS, il faut obtenir un certificat auprès d’une autorité de certification, et c’est payant…
Le cookie fantôme de Google
Je vous avais dit que ça n’aurait rien à voir. Depuis un certain temps, je recherche un moyen d’empêcher Google de collecter mes données personnelles, tout en conservant mes paramètres de recherche (en particulier, toujours avoir la recherche instantanée
désactivée – je ne supporte pas ça).
On trouve quelques idées là-dessus sur le Net, mais toutes les solutions que j’ai pu trouver sont obsolètes, à cause de la façon opaque et désorganisée (pour ne pas dire anarchique) dont Google fait évoluer son interface. Cependant, un script pas trop vieux trouvé sur Userscripts.org (màj : le site est mort depuis août 2014) m’a mis sur la piste de la fabrication de cookies. L’idée est simple : les préférences sont stockées dans un cookie appelé PREF
. Il me suffit de recréer ce cookie à chaque fois que j’utilise Google. Ainsi, je n’ai plus besoin de le conserver et je peux configurer mon navigateur pour qu’il supprime les cookies de Google à la fermeture.
J’ai donc commencé à faire des tests sur ce cookie PREF
avec ma console JavaScript habituelle, Firebug. Là, un détail m’a paru bizarre. Un détail que je n’avais pas remarqué tout de suite, car j’avais nettoyé manuellement tous mes cookies Google avant de commencer. Je croyais que Google n’avait recréé que PREF
, et tous mes tests avec Firebug m’indiquaient qu’il était bien le seul cookie du site. Mais il était là, sous mes yeux, dans la fenêtre de gestion des cookies de Firefox : un second cookie, nommé NID
. Une aberration. Un fantôme. Il était bien présent, je le voyais dans les en-têtes HTTP envoyés au serveur. Mais invisible pour JavaScript. Pire : j’ai tenté de l’écraser avec une nouvelle valeur, et j’ai vu apparaître un deuxième cookie NID
, avec effectivement la nouvelle valeur, mais aussi avec le même nom et les mêmes propriétés que le premier ! J’ai cru que j’avais rompu les lois de la physique et que l’univers allait s’effondrer.
Non, plus sérieusement, j’ai cru qu’il s’agissait d’un bug de Firefox, et ça ne m’a pas aidé à orienter mes recherches, puisqu’en fait ça n’en était pas un. Il s’agit d’un cookie HTTP-only, petit être timide qui, comme son nom l’indique, ne se montre que pour le protocole HTTP.
Or, techniquement parlant, il se trouve que JavaScript est un protocole. Rappelez-vous : n’avez-vous jamais vu de lien <a href="javascript:…">
? Remarquez qu’on peut aussi taper du code commençant par javascript:
dans la barre d’adresse (même si les navigateurs récents ont tendance à désactiver cette fonctionnalité). Et finalement, on peut aussi mettre des marque-page sur du code JavaScript : c’est le principe des bookmarklets.
Pour revenir à nos cookies HTTP-only, il est logique que JavaScript ne puisse pas y accéder puisque JavaScript n’est pas HTTP. La présence de mon deuxième NID
, quant à elle, s’explique par le fait qu’il porte la propriété HttpOnly
, ce qui en fait un cookie différent, même si ce n’est pas visible dans la fenêtre de gestion.
Le serveur est le seul maître avec ce type de cookie. Il peut les lire comme des cookies normaux ; il peut les créer ou les modifier en ajoutant un en-tête Set-Cookie
personnalisé, par exemple :
Set-Cookie: reponse=42; domain=kergoz-panic.fr; path=/; HttpOnly
Le navigateur se contente de renvoyer ce type de cookies au serveur, sans pouvoir les examiner ni les manipuler. Imaginez, c’est un peu comme si le serveur distribuait des balles de différentes couleurs à des aveugles, en se servant des couleurs pour se rappeler le nom de chaque personne.
Il me semble évident que cette fonctionnalité a été imaginée pour protéger des cookies contenant des données sensibles. Les cookies de session sont un bon exemple. Grâce à HTTP-only, le vol de cookie par attaque XSS devient inefficace – et souvenez-vous que personne n’est à l’abri d’une XSS, pas même Youtube. Reprenons la métaphore des balles colorées : j’ai au téléphone un des aveugles, et j’exerce sur lui un contrôle mental (attaque XSS) pour lui faire avouer de quelle couleur est sa balle. Peine perdue, puisqu’il est aveugle…
Le détail qui tue, c’est que les cookies HTTP-only ont été introduits en 2002 par Microsoft pour la version SP1 de IE6 ! Un comble, quand on connaît le niveau général de sécurité dans ce navigateur.
Ce qui m’étonne, c’est que cette fonctionnalité n’ait pas été adoptée plus tôt. Le plus précoce a été Firefox 2 en 2006, soit quatre ans plus tard ! Et à ce moment-là, la protection n'était pas parfaite, car bien qu’on ne pût pas lire les cookies HTTP-only, on pouvait néanmoins les modifier. À l’heure où j’écris ces lignes, Opera n’offre toujours pas un support complet, et Safari est loin derrière les autres… En revanche, Google Chrome est irréprochable là-dessus, mais puisque vous avez lu les paragraphes précédents, ça ne vous étonnera pas.
En conclusion, le support des cookies HTTP-only est encore très incomplet, mais que cela ne nous empêche pas d’en faire un usage abusif : cela protègera déjà une partie de nos visiteurs, et ça ne peut aller qu’en s’améliorant.
Le double cookie de session de Toile-Libre
Si vous examinez les cookies des pages de Kergoz-Panic, vous en verrez deux : PHPSESSID
et SERVERID
. Le premier est, comme on l’a vu, le cookie de session. Actuellement, la session pour les visiteurs de Kergoz-Panic ne sert qu’à une chose : mémoriser l’image d’en-tête (pour les rédacteurs, bien sûr, elle permet de se connecter à l’interface d’administration). Si vous supprimez PHPSESSID
, votre session va changer, et vous recevrez une nouvelle image d’en-tête choisie aléatoirement (il y a une chance que ce soit la même).
Quand j’ai vu le contenu du cookie SERVERID
, j’ai d’abord cru que c’était le résidu d’un test que j’avais fait assez longtemps auparavant pour ne pas m’en souvenir. Avec des valeurs tout à fait sérieuses et explicites telles que prozac
ou encore turlute
, il y avait toutes les chances que ce soit de mon fait. Mais non. En fait il s’agit du nom d’un serveur physique de Toile-Libre, celui qui distribue les pages de Kergoz-Panic pour votre session. Pourquoi ils ont besoin d’un cookie pour ça, je n’en sais rien et je ne tiens pas à le savoir. Je crois que j’ai eu ma dose avec les sorcelleries de cet hébergeur…
Commentaires
Aucun commentaire n’a encore été posté sur cet article.