Vérificateur de sécurité des cookies

Trois flags décident si une session peut être volée.

Saisissez une URL et nous listons les cookies que votre site dépose, en vérifiant sur chacun Secure, HttpOnly et SameSite. Les cookies de session sont l'identifiant que vos utilisateurs ne voient jamais, et ces trois attributs constituent l'essentiel de leur protection.

Examinez des sites qui vous appartiennent ou que vous êtes autorisé à tester. Nous demandons la page comme le ferait un navigateur et lisons ce qui revient. Consultez nos conditions.

Ce que cela vérifie, et à quoi ressemble une bonne réponse

Secure

Sans lui, le navigateur enverra le cookie en http simple autant qu'en https. Cela semble théorique jusqu'à ce qu'on se rappelle comment ça se produit vraiment : un utilisateur tape votre domaine sans le schéma, ou clique sur un vieux lien http, le navigateur fait une requête non chiffrée avant que votre redirection ne se déclenche, et le cookie de session part en clair sur le réseau où cette personne se trouve. La redirection ne vous sauve pas, puisque le cookie a déjà été envoyé. Tout cookie qui identifie un utilisateur a besoin de ceci.

HttpOnly

Sans lui, document.cookie peut lire la valeur, ce qui veut dire que n'importe quel script de la page le peut. C'est tout le gain d'un bug de cross-site scripting : l'attaquant n'a besoin de rien d'ingénieux une fois qu'il peut lire le cookie de session, il le prend et devient cet utilisateur. Avec HttpOnly posé, le même bug reste un bug, mais la session y survit. C'est ce flag qui décide du coût de votre prochain XSS.

SameSite

Si le cookie est joint aux requêtes venant d'autres sites. Sans valeur posée, un formulaire sur la page de quelqu'un d'autre peut poster vers votre endpoint et le navigateur y joindra obligeamment la session : c'est le cross-site request forgery. Lax est la valeur sensée et c'est ce que les navigateurs modernes supposent quand l'attribut est absent, mais supposer une valeur par défaut n'équivaut pas à la déclarer, et les vieux clients ne la supposent pas. Strict est plus sûr et déconnectera les gens qui arrivent depuis un lien externe. None n'est légitime que pour un usage cross-site réel et exige Secure à ses côtés.

Quels cookies nous jugeons, et lesquels nous laissons passer

Tous les cookies n'ont pas besoin de tous les flags. Un cookie d'analytique ou de préférence qui ne porte aucune identité ne vaut pas d'être verrouillé, et le signaler vous entraînerait à ignorer le rapport. Nous pesons ceux dont le nom évoque une session et une authentification, parce que ce sont ceux où un flag manquant a une conséquence réelle.

Comment corriger

Ces flags se posent là où le cookie est créé, pas dans un fichier de configuration global, et c'est pour cela qu'ils passent à la trappe : il n'y a pas un endroit unique où les corriger et chaque bibliothèque les écrit à sa façon. Les exemples ci-dessous posent les trois d'un coup.

L'en-tête lui-même
Set-Cookie: session=abc123; Path=/; Max-Age=604800;
  Secure;
  HttpOnly;
  SameSite=Lax

# Secure   -> https only
# HttpOnly -> invisible to document.cookie
# SameSite -> not sent on cross-site requests

# Note: SameSite=None REQUIRES Secure, and browsers drop the cookie
# entirely if you set None without it. That silent drop is a common
# cause of "my login works locally and not in production".
Next.js
import { cookies } from "next/headers";

(await cookies()).set("session", token, {
  httpOnly: true,
  secure: process.env.NODE_ENV === "production",
  sameSite: "lax",
  path: "/",
  maxAge: 60 * 60 * 24 * 7,
});
Express
// Behind a proxy or load balancer, "secure" cookies are dropped
// unless Express is told to trust the forwarded protocol. Missing
// this is why the flag silently does nothing in production.
app.set("trust proxy", 1);

res.cookie("session", token, {
  httpOnly: true,
  secure: true,
  sameSite: "lax",
  maxAge: 1000 * 60 * 60 * 24 * 7,
});
Hono, Fastify et compagnie
// Hono
import { setCookie } from "hono/cookie";

setCookie(c, "session", token, {
  httpOnly: true,
  secure: true,
  sameSite: "Lax",
  path: "/",
  maxAge: 60 * 60 * 24 * 7,
});

// Fastify (@fastify/cookie)
reply.setCookie("session", token, {
  httpOnly: true,
  secure: true,
  sameSite: "lax",
  path: "/",
});
Ce que cet outil ne peut pas voir

Nous voyons les cookies que votre site dépose sur la seule page que nous avons demandée, avant toute authentification. Les cookies qui comptent le plus sont généralement posés au moment où quelqu'un se connecte, sur une réponse que nous ne recevons jamais : un résultat propre ici ne prouve donc pas que votre cookie de session est correct. Regardez aussi la réponse à votre propre requête de connexion dans les devtools. Et les flags ne sont que la moitié transport du problème : ils ne disent rien de la durée de la session, de son invalidation à la déconnexion, ni de la possibilité de forger le token qu'elle contient.

Scanner aussi le codeGratuit pour démarrer. Connectez un dépôt et le premier scan tourne en deux minutes environ.