Toute la sécurité côté navigateur repose sur un mur unique, dont il faut avoir la définition exacte en tête avant d’aborder quoi que ce soit d’autre : la Same-Origin Policy (SOP).

Le mur de base

Le navigateur charge un document HTML depuis une origine — le triplet schéma (https), hôte, port — et son DOM devient manipulable par JavaScript. La SOP restreint alors ce que du code exécuté sur une origine peut faire d’une autre : elle interdit l’accès au DOM d’une autre page, l’accès aux cookies ou au localStorage d’une autre origine, et la lecture des réponses XHR/fetch cross-origin.

IMPORTANT

La SOP est le mur de base de la sécurité côté navigateur. Tout le reste — XSS, CORS, CSRF — n’est qu’une manière de détourner, d’assouplir ou de renforcer ce mur. Comprendre une vulnérabilité web, c’est presque toujours comprendre comment elle contourne ou exploite la SOP.

Cookies et session

Le serveur mémorise l’état d’un utilisateur entre deux requêtes via l’en-tête Set-Cookie ; le navigateur stocke la valeur et la renvoie automatiquement à chaque requête vers le même domaine. C’est ce mécanisme, en apparence anodin, qui porte toute la notion de session — et toute sa fragilité.

Trois attributs modernes déterminent la robustesse d’un cookie de session :

Secure limite l’envoi du cookie au seul HTTPS, évitant qu’il ne fuite en clair si un utilisateur visite par erreur la version non chiffrée d’un site.

HttpOnly rend le cookie invisible depuis document.cookie : le JavaScript, même légitime, ne peut plus le lire.

console.log(document.cookie); // ne retourne rien pour un cookie HttpOnly

Ce que HttpOnly ne protège pas

HttpOnly n’empêche pas un XSS d’utiliser la session : le cookie continue d’être envoyé automatiquement par le navigateur, et un script injecté peut toujours déclencher des requêtes authentifiées en votre nom. Il empêche le vol direct du cookie, pas l’abus de la session qu’il porte.

SameSite répond à une question différente : faut-il envoyer ce cookie lors d’une requête cross-site ? Trois valeurs se distinguent. Lax (la valeur par défaut) n’envoie pas le cookie pour la plupart des requêtes cross-site (image, XHR, iframe, POST), mais l’envoie tout de même pour une navigation de premier niveau en GET — un clic sur un lien, une redirection. Strict va plus loin : même un lien cliqué depuis un autre site n’envoie pas le cookie. None; Secure autorise explicitement les cookies tiers, nécessaires par exemple pour une authentification SSO en iframe, des widgets cross-site, ou des produits SaaS embarqués (Stripe, Zendesk, Intercom).

Ces trois flags, combinés, forment la première ligne de défense contre le vol et l’abus de session — mais aucun d’eux, on le verra, ne suffit seul contre un XSS ou une CSRF bien construite.