Cookies HTTP : pourquoi ne jamais y fonder une décision de droits
Un cookie est un fragment d’état que le serveur demande au navigateur de conserver et de renvoyer à chaque requête. La donnée vit donc côté client, hors de tout contrôle du serveur entre deux échanges. Un utilisateur peut la lire, la modifier et la rejouer à volonté. Fonder une gestion de droits ou un accès à des ressources sur la valeur d’un cookie est de ce fait une erreur de conception.
Le mécanisme du cookie
Section intitulée « Le mécanisme du cookie »Le serveur émet un cookie via l’en-tête Set-Cookie, le navigateur le renvoie ensuite dans l’en-tête Cookie :
# Réponse du serveurSet-Cookie: role=user; Path=/
# Requêtes suivantes du clientCookie: role=userDes attributs encadrent son usage : Path et Domain délimitent sa portée, Expires sa durée de vie, HttpOnly le rend inaccessible au JavaScript, Secure le réserve à HTTPS, SameSite limite l’envoi cross-site. Ces attributs protègent contre le vol ou l’envoi involontaire du cookie. Aucun n’empêche son propriétaire légitime de le modifier.
L’anti-pattern : la confiance dans la valeur
Section intitulée « L’anti-pattern : la confiance dans la valeur »Le défaut consiste à placer une information d’autorisation directement dans un cookie en clair, puis à s’y fier côté serveur.
Cookie: role=userCookie: isAdmin=0Cookie: user_id=1042Le serveur qui lit role pour décider d’un accès, ou isAdmin pour ouvrir une interface d’administration, délègue sa décision de sécurité à une donnée que le client contrôle entièrement.
Exploiter en altérant le cookie
Section intitulée « Exploiter en altérant le cookie »L’attaque ne demande aucun outil sophistiqué. La valeur se change dans l’inspecteur du navigateur (onglet Application → Cookies) ou en interceptant la requête dans Burp Suite.
# Cookie d'origineCookie: role=user
# Cookie modifié, rejoué tel quelCookie: role=adminSi le serveur accorde des droits d’administration sur la seule foi de role=admin, l’élévation de privilèges est immédiate. Le même raisonnement s’applique à isAdmin=0 passé à 1, ou à un user_id changé pour usurper un autre compte.
Le point à retenir : un cookie peut être altéré comme on le veut, et le serveur ne dispose d’aucun moyen de le savoir si la valeur n’est ni signée ni vérifiée.
Signer ne suffit pas à autoriser
Section intitulée « Signer ne suffit pas à autoriser »Signer ou chiffrer le cookie empêche l’altération silencieuse, comme le fait Flask avec itsdangerous ou un JWT avec sa signature. C’est un prérequis d’intégrité, mais pas une politique d’autorisation.
- Une signature ne protège que si sa clé est forte. Un secret faible se casse hors ligne, et le cookie redevient forgeable.
- Même signé, un cookie qui porte un rôle reste une affirmation du client. Le serveur doit confronter cette affirmation à une source de vérité, pas la prendre pour argent comptant.
Remédiation
Section intitulée « Remédiation »Décider des droits côté serveur
Section intitulée « Décider des droits côté serveur »L’autorisation se calcule côté serveur, à partir de l’identité authentifiée et d’un référentiel de droits maîtrisé (base de données, annuaire). Le cookie sert à identifier une session, jamais à porter la décision.
# Vulnérable : le rôle vient du cookieif request.cookies.get("role") == "admin": show_admin_panel()
# Correct : le rôle est lu côté serveur pour l'utilisateur authentifiéuser = get_user_from_session(request)if user.has_role("admin"): show_admin_panel()Utiliser un identifiant de session opaque
Section intitulée « Utiliser un identifiant de session opaque »Un cookie de session doit contenir un identifiant aléatoire sans signification, associé côté serveur à l’état réel de la session. Rien d’exploitable ne transite alors par le client.
Set-Cookie: SESSIONID=b7c9f1e0a4d84e2fa1c3; HttpOnly; Secure; SameSite=Strict; Path=/Poser les attributs de protection
Section intitulée « Poser les attributs de protection »HttpOnly, Secure et SameSite ne corrigent pas le problème d’autorisation, mais ils limitent le vol du cookie par XSS, son interception en clair et son envoi cross-site. Ils font partie de la configuration minimale d’un cookie de session.
À retenir
Section intitulée « À retenir »Un cookie est une donnée cliente, modifiable par nature. Y inscrire un rôle ou un droit et s’y fier côté serveur ouvre une élévation de privilèges qui ne demande qu’un clic dans l’inspecteur. Signer le cookie protège son intégrité mais ne remplace pas une vérification : l’autorisation se décide côté serveur, à partir d’une source de confiance, et le cookie se limite à identifier une session par un jeton opaque.