← Toutes les vérifications
SécuritéSévérité typique: Moyen

Cache de réponses avec session

Détecte des réponses avec un cookie de session marquées comme cachables, qu'un CDN partagé pourrait servir à un autre utilisateur.

Ce qu'elle vérifie

Ce scanner passe en revue les réponses de ton site qui portent un cookie de session et vérifie si elles sont marquées comme cachables. Il détecte quand une page personnalisée ou liée à une session pourrait être stockée dans un cache partagé comme un CDN ou un proxy intermédiaire.

Pourquoi ça compte

Si une réponse liée à la session d'un utilisateur est stockée dans un cache partagé, ce cache peut finir par la servir à une personne complètement différente. Ça veut dire qu'un visiteur pourrait voir le compte, les données ou la session d'un autre, ce qui est une fuite d'information sérieuse.

Comment la corriger

Assure-toi que toute réponse contenant des données de session porte des en-têtes qui empêchent la mise en cache, comme Cache-Control avec private et no-store. Revois les réglages de ton CDN ou de ton proxy pour qu'il ne stocke jamais de pages associées à un cookie de session.

Comment fonctionne cette vérification

Scanaris regarde la réponse principale de ta page et vérifie deux conditions à la fois. Première : la réponse pose au moins un cookie (Set-Cookie) dont le nom commence par sess, sid, auth, token, jwt, connect.sid, phpsessid ou asp.net, c'est-à-dire un cookie qui identifie selon toute probabilité une session. Seconde : la même réponse porte Cache-Control avec la directive public. Seulement si les deux sont réunies, il ouvre un constat de sévérité moyenne avec le nom du cookie et la valeur de l'en-tête. C'est volontairement strict : un cookie de préférences avec cache public, ou un cookie de session sans public, ne sont pas signalés.

Pourquoi c'est important

Cache-Control: public est une instruction explicite à tout cache partagé (un CDN, un proxy inverse comme Varnish ou nginx, le proxy d'une entreprise ou d'un opérateur) indiquant que cette réponse peut être stockée et servie à d'autres utilisateurs. Si cette même réponse inclut un Set-Cookie de session, le cache peut stocker le cookie avec le corps et le donner au visiteur suivant. Ce visiteur entre avec la session du précédent, sans mot de passe, et voit ses données. C'est le genre de faille qu'on découvre quand un client écrit pour dire qu'il « est entré dans le compte de quelqu'un d'autre ». C'est arrivé à des banques et à de grands commerçants, toujours par la même combinaison : du contenu personnalisé marqué comme cachable.

D'où ça vient

Généralement d'une règle de cache trop large : un add_header Cache-Control "public, max-age=3600" dans nginx appliqué à toutes les routes, y compris celles qui créent une session ; une règle « Cache Everything » dans Cloudflare ; ou un routeRules avec des en-têtes de cache pour '/**' dans une appli qui pose des cookies sur la page principale. La plupart des CDN refusent de stocker les réponses avec Set-Cookie par défaut, et nginx aussi sauf si tu lui dis d'ignorer cet en-tête, mais un public explicite, c'est toi qui leur dis de le faire.

Comment corriger

  • Les réponses qui créent ou renouvellent une session portent Cache-Control: private, no-store. C'est ce que font par défaut express-session, Laravel, Django et Rails ; si tu vois public, une couche ultérieure l'a ajouté.
  • Sépare les règles de cache par type de route. public avec un max-age long pour les fichiers statiques avec hash dans le nom (/_nuxt/, /_next/static/, /assets/) ; private ou no-store pour le HTML qui dépend de l'utilisateur. Dans nginx, utilise des blocs location distincts ; dans Nuxt et Next.js, des règles par route plutôt qu'une règle globale.
  • Ne pose pas le cookie de session sur des pages publiques cachables. Si l'accueil n'a pas besoin de session, il ne doit pas en créer : crée le cookie à la connexion ou à l'entrée dans le tableau de bord.
  • Si tu utilises un CDN avec « Cache Everything » ou équivalent, ajoute une règle pour ne pas cacher les réponses avec Set-Cookie ni les routes authentifiées. Et ajoute Vary: Cookie comme filet supplémentaire, sans que ça remplace ce qui précède.

Vérifie que c'est corrigé

curl -sI https://tondomaine.com | grep -iE "^(set-cookie|cache-control|vary):"
curl -sI https://tondomaine.com/dashboard | grep -iE "^(set-cookie|cache-control):"

S'il y a un Set-Cookie avec un nom de session, le Cache-Control de cette réponse doit être private, no-store ou no-cache, jamais public. Fais la seconde requête avec et sans ton cookie de session : la réponse authentifiée ne doit jamais apparaître sans lui.

Questions fréquentes

Mon CDN dit qu'il ne cache pas les réponses avec cookies. C'est donc un faux positif ?

La fuite ne se produit probablement pas aujourd'hui, mais tu dépends d'un comportement par défaut qu'une nouvelle règle ou un changement de fournisseur peuvent désactiver. L'en-tête dit que c'est public ; corrige l'en-tête et cesse de dépendre de l'exception.

Et les cookies d'analyse ou de consentement ?

Ils ne sont pas signalés : seuls les noms qui indiquent une session comptent. Un cookie de consentement sur une page publique en cache est normal. La façon dont les cookies de session doivent être configurés (Secure, HttpOnly, SameSite) est couverte par cookies non sécurisés.

Ma session est un jeton dans localStorage, pas un cookie.

Alors cette vérification ne s'applique pas, mais jeton dans le stockage si : un jeton accessible depuis JavaScript a d'autres problèmes.

Vérifie-le sur ton site

Analyse ton site gratuitement et vois si celle-ci et 44 autres vérifications passent, avec un fix prompt pour chaque problème.

Analyser mon site gratuitement

Vérifications liées