Jour 1 · Section 2 · Lab guidé

Cookies, SameSite et domaines

Observez ce que JavaScript peut lire, quels cookies le navigateur envoie et ce qui change lorsqu’une requête vient d’un autre site.

Environnement contrôlé uniquement. Réalisez cette démonstration exclusivement sur training.dercetech.com, training2.dercetech.com et training.bad-sector.games, avec les identifiants fictifs fournis. N’utilisez jamais de cookie ou de compte réel.

Ouvrir l’application volontairement vulnérable

Accéder à unsafe/

Authentifiez-vous avec admin / password. Le champ « Display name » accepte un prénom fictif, par exemple Alex.

Observer les cookies volontairement trop larges

Ouvrez DevTools → Network, reconnectez-vous, sélectionnez login.php puis lisez les lignes brutes Set-Cookie dans Response Headers. C’est là que vous pouvez confirmer quels attributs le serveur a réellement envoyés.

AttributÉtat initial à constater
Domain.dercetech.com : volontairement large pour la démonstration avec le sous-domaine adjacent.
HttpOnlyAbsent : JavaScript peut lire les deux cookies.
Path/ : les cookies couvrent tout le domaine indiqué.
SameSiteLax : le cookie est bloqué pour certaines requêtes provenant d’un autre site (cross-site), mais pas pour toutes.

Ouvrez ensuite Application (ou Storage) → Cookies. Ici, les lignes brutes et cette vue doivent toutes deux montrer le domaine large et le chemin /.

Vous verrez aussi demo_theme, un cookie séparé qui mémorise la couleur utilisée dans l’exercice SameSite S2.03. Il est limité à training.dercetech.com, utilise SameSite=Lax et reste volontairement lisible par JavaScript : il n’a pas l’attribut HttpOnly.

Ce périmètre trop large est intentionnel pour le laboratoire : HttpOnly et Secure restent absents. SameSite=Lax est présent afin de comparer une requête en arrière-plan et une navigation GET. Ne reproduisez pas cette configuration en production.

Ouvrir le sous-domaine adjacent

Cette page doit voir session et whoami, car ils couvrent .dercetech.com, utilisent le chemin / et restent lisibles par JavaScript. Elle n’envoie et ne stocke rien.

Lire la valeur visible

Dans la Console, exécutez document.cookie. Vous devez voir session et whoami : c’est exactement ce qu’un script injecté sur cette page pourrait lire.

Voir ce que le site espion a reçu

Ouvrir le tableau de bord du site espion

La page unsafe/welcome.php charge volontairement un script visible. Ce script lit les cookies accessibles à JavaScript, puis les envoie avec le marqueur D1/S2. Le tableau de bord affiche au maximum les 20 derniers envois fictifs, du plus récent au plus ancien. N’utilisez jamais de cookie réel.

Lancer l’exercice SameSite local (S2.03)

Dans votre copie du cours, ouvrez day-1/s2_03_samesite/README.md. Lancez la version Flask ou la version Express.

Ouvrir le site espion local

Le lien fonctionne lorsque votre serveur local est lancé. Les boutons Tester fetch() et Voir une photo de chat (navigation GET) se trouvent sur cette page locale, pas sur la présente page de consignes.

Les deux versions servent exactement la même page. Elles n’essaient pas de lire directement les cookies de dercetech.com : le navigateur sépare les cookies de ces deux sites.

Comparer fetch() et une navigation GET

Vérifiez d’abord que l’application vulnérable indique un fond bleu. Dans DevTools → Application (ou Storage) → Cookies, demo_theme vaut blue. Sur le site local, cliquez sur Tester fetch(). La requête atteint la route GET, mais le navigateur ne lui joint pas le cookie de session SameSite=Lax. Le serveur répond 401 et la couleur reste bleue.

Cliquez ensuite sur Voir une photo de chat (navigation GET). Ce lien trompeur ouvre la même route comme page principale. Le navigateur peut alors joindre le cookie de session Lax, et la route remplace demo_theme=blue par demo_theme=red.

La page distante reste affichée : elle ne redirige pas automatiquement et ne transmet ni le prénom ni les cookies au site local. Celui-ci a seulement provoqué une action authentifiée. Chaque élève voit le résultat dans son propre navigateur ; aucune couleur n’est partagée sur le serveur.

Conclusion : SameSite=Lax bloque de nombreuses requêtes cross-site en arrière-plan, mais une route GET ne doit jamais modifier l’état d’un compte.