Les cookies sont la fondation de la gestion des sessions sur le web. Ils stockent vos tokens d'authentification, vos préférences utilisateur, vos paniers e-commerce. Et précisément parce qu'ils contiennent des données aussi sensibles, ils sont une cible de choix pour les attaquants.
La bonne nouvelle : sécuriser correctement vos cookies nécessite principalement de bien configurer quelques attributs. Ce guide vous montre lesquels, pourquoi, et comment vérifier que tout est en place.
Les Deux Risques Principaux
Vol de session (Session Hijacking)
Si un attaquant obtient votre cookie de session, il peut se faire passer pour vous sans connaître votre mot de passe. C'est l'équivalent numérique d'obtenir le badge d'accès d'un employé.
Le vol peut se produire via :
- Attaque XSS : un script malveillant lit
document.cookieet envoie les valeurs vers un serveur distant - Interception réseau : sur un réseau non chiffré (Wi-Fi public), un attaquant peut capturer le trafic HTTP
- Accès physique : consultation des cookies dans les DevTools sur un poste partagé
CSRF (Cross-Site Request Forgery)
Une attaque CSRF trompe votre navigateur en lui faisant envoyer une requête authentifiée vers votre site depuis un autre site. Le navigateur inclut automatiquement les cookies, donc la requête semble légitime.
Exemple : vous êtes connecté à votre banque en ligne. Vous visitez un site malveillant qui contient une image dont l'URL est https://votre-banque.com/virement?montant=5000&destinataire=attaquant. Votre navigateur charge "l'image", envoie la requête avec vos cookies, et le virement est effectué.
Les 5 Attributs de Sécurité
1. HttpOnly
Set-Cookie: session_id=abc123; HttpOnly
Effet : le cookie est inaccessible via JavaScript (document.cookie).
Protège contre : les attaques XSS qui tentent de voler les cookies. Même si un attaquant injecte du JavaScript dans votre page, il ne peut pas lire les cookies HttpOnly.
Quand l'utiliser : sur tous les cookies d'authentification et de session, sans exception. Les cookies qui ont besoin d'être lus par JavaScript (analytics, preferences UI) peuvent ne pas avoir cet attribut, mais jamais les cookies de session.
2. Secure
Set-Cookie: session_id=abc123; HttpOnly; Secure
Effet : le cookie n'est transmis que sur des connexions HTTPS.
Protège contre : l'interception sur des réseaux non chiffrés. Sans cet attribut, un utilisateur sur un Wi-Fi public peut voir ses cookies transmis en clair.
Quand l'utiliser : sur tous les cookies en production. En développement local (HTTP), vous pouvez omettre temporairement cet attribut.
3. SameSite
Set-Cookie: session_id=abc123; HttpOnly; Secure; SameSite=Strict
Trois valeurs possibles :
| Valeur | Comportement | Protection CSRF |
|--------|-------------|-----------------|
| Strict | Cookie jamais envoyé depuis un autre site | Maximale |
| Lax | Cookie envoyé uniquement pour les navigations GET de premier niveau | Bonne (défaut) |
| None | Cookie envoyé dans tous les contextes cross-site | Aucune (requiert Secure) |
Recommandation :
- Cookies de session d'application :
SameSite=Strict - Cookies nécessaires pour les widgets tiers (boutons de partage, iframes) :
SameSite=None; Secure - Comportement par défaut des navigateurs modernes :
Laxsi non spécifié
Quand utiliser Strict vs Lax : Strict protège mieux mais casse la navigation depuis des liens externes. Si un utilisateur clique sur un lien vers votre application depuis son client email, avec Strict il ne sera pas authentifié (cookie non transmis). Lax est souvent le bon compromis.
4. Path
Set-Cookie: admin_token=xyz; Path=/admin; HttpOnly; Secure
Effet : le cookie n'est transmis que pour les requêtes vers le chemin spécifié.
Intérêt : limiter la surface d'exposition. Un cookie d'administration n'a pas besoin d'être envoyé avec chaque requête sur /public ou /api/v1/public.
5. Domain et Expires/Max-Age
Set-Cookie: session_id=abc123; HttpOnly; Secure; SameSite=Strict; Max-Age=3600
Domain : limite le cookie à un domaine et ses sous-domaines. Si omis, le cookie s'applique au domaine exact uniquement (plus sécurisé).
Max-Age / Expires : durée de vie. Les cookies sans expiration sont des cookies de session (supprimés à la fermeture du navigateur). Les cookies avec expiration persistent.
Pour les tokens de session : préférer une durée courte (1-24h) avec renouvellement automatique, plutôt qu'une durée longue qui augmente la fenêtre de risque.
Implémentation par Langage
Node.js / Express
// Configuration sécurisée des cookies de session
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
maxAge: 60 * 60 * 1000, // 1 heure
}
}))
PHP
// Configuration globale dans php.ini ou via ini_set
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 1);
ini_set('session.cookie_samesite', 'Strict');
// Ou à la création du cookie
setcookie(
'session_token',
$token,
[
'expires' => time() + 3600,
'path' => '/',
'domain' => '.votredomaine.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict'
]
);
Next.js avec NextAuth v5
// auth.config.ts
export const authConfig = {
cookies: {
sessionToken: {
options: {
httpOnly: true,
sameSite: 'lax',
path: '/',
secure: process.env.NODE_ENV === 'production',
},
},
},
}
Auditer Vos Cookies Actuels
Avec les DevTools du navigateur
- Ouvrez les DevTools (F12)
- Onglet "Application" (Chrome) ou "Stockage" (Firefox)
- Section "Cookies" dans la navigation gauche
- Pour chaque cookie, vérifiez les colonnes : HttpOnly, Secure, SameSite
Les cookies de session sans HttpOnly ou sans Secure sont des signaux d'alerte immédiats.
Avec curl
# Voir les headers Set-Cookie d'une réponse
curl -sI https://votredomaine.com/login \
-c /tmp/cookies.txt \
-d "username=test&password=test" | grep -i "set-cookie"
Points de contrôle
- [ ] Tous les cookies de session ont
HttpOnly - [ ] Tous les cookies ont
Secureen production - [ ] Tous les cookies ont
SameSiteexplicitement défini - [ ] Les cookies d'administration ont un
Pathrestrictif - [ ] La durée de vie des sessions est raisonnable (moins de 24h pour les applications sensibles)
- [ ] Pas de données sensibles stockées dans les cookies (uniquement les identifiants)
Erreurs Courantes
Stocker des données sensibles dans les cookies : un cookie peut être décodé facilement (base64, JSON). Ne stockez jamais de mot de passe, numéro de carte, ou données personnelles dans un cookie. Stockez uniquement un identifiant de session, et gardez les données en serveur.
Confondre HTTPS et Secure : Secure ne chiffre pas le cookie. C'est HTTPS qui chiffre la transmission. Secure s'assure simplement que le cookie ne circule que sur des connexions chiffrées.
Session sans invalidation côté serveur : même avec les bons attributs, si vous ne pouvez pas invalider une session côté serveur (déconnexion, changement de mot de passe), un cookie volé reste exploitable jusqu'à son expiration.
Monitoring avec WarDek
WarDek analyse les headers Set-Cookie de vos réponses HTTP et identifie automatiquement les cookies mal configurés. Chaque cookie est évalué sur les cinq attributs de sécurité, avec une explication de l'impact et la correction recommandée.
Notre scanner teste également les scénarios d'attaque XSS liés aux cookies — consultez notre guide sur la protection XSS pour comprendre comment les deux problématiques sont liées.
La configuration correcte des cookies est une mesure à coût quasi nul qui élimine des classes entières d'attaques. Il n'y a aucune raison de ne pas l'appliquer dès aujourd'hui.