Chapitre 2.1 — Requête, origine & Same-Origin Policy
⏱️ TL;DR — Une requête HTTP, c’est une méthode (
GET,POST…), une URL, des en-têtes (dontCookie,Authorization,Origin) et parfois un corps. Le serveur ne « voit » que ce que le client lui envoie — et le client peut tout falsifier. Le navigateur, lui, isole les sites entre eux grâce à la Same-Origin Policy (SOP) : une origine = schéma + hôte + port, et par défaut le code d’une origine ne peut pas lire les réponses d’une autre. Cette isolation est le socle de la sécurité web ; la comprendre, c’est comprendre ce que le CSRF, le XSS et CORS cherchent respectivement à contourner ou à assouplir.
🎯 Objectifs
- Lire l’anatomie d’une requête et d’une réponse HTTP, et repérer les parties sensibles.
- Comprendre que tout ce qui vient du client est falsifiable (y compris les en-têtes).
- Définir une origine précisément et savoir quand deux URL sont « same-origin » ou non.
- Expliquer ce que la Same-Origin Policy interdit et autorise — et pourquoi elle est le socle du web.
Anatomie d’une requête HTTP
Quand ton navigateur charge une page ou que ton fetch part, voici ce qui transite réellement :
POST /api/login HTTP/1.1
Host: app.formacampus.fr
Content-Type: application/json
Cookie: session=abc123; theme=dark
Origin: https://app.formacampus.fr
User-Agent: Mozilla/5.0 ...
{"email":"lea@ecole.fr","password":"..."}Décomposons les parties qui comptent pour la sécurité :
- La méthode (
POST) et le chemin (/api/login) : quoi faire, sur quelle ressource. Host: le domaine visé (un même serveur peut héberger plusieurs sites).Cookie: les cookies que le navigateur attache automatiquement pour ce domaine — c’est la clé de la session, et la raison d’être du CSRF.Origin/Referer: d’où part la requête (utile pour détecter une requête cross-site).- Le corps : les données envoyées (ici les identifiants).
Côté réponse, le serveur renvoie un statut (200, 403…), des en-têtes (dont Set-Cookie, et tous les en-têtes de sécurité du chapitre 2.4) et un corps.
⚠️ Piège — Tout ce qu’un client envoie est falsifiable : la méthode, le chemin, le corps, et les en-têtes.
User-Agent,Referer,X-Forwarded-For, un en-tête « custom »X-Is-Admin: false… un attaquant met ce qu’il veut aveccurlou un proxy. Ne fais jamais reposer une décision de sécurité sur un en-tête que le client contrôle (« je fais confiance auReferer», « siX-Requested-Withest là c’est que ça vient de mon front » — non). La confiance vient de ce que le serveur établit (session validée), pas de ce que le client déclare.
Le navigateur fait des choses tout seul
Point crucial pour comprendre le CSRF : le navigateur attache automatiquement certaines informations aux requêtes vers un domaine, sans demander au JavaScript de la page. En particulier, les cookies d’un domaine partent avec toute requête vers ce domaine — que la requête soit déclenchée par ton code, par un clic, par une balise <img>, ou par un formulaire sur un autre site.
C’est très pratique (tu restes connecté), mais c’est aussi le mécanisme qu’exploite le CSRF : si un site malveillant fait envoyer au navigateur d’une victime une requête vers app.formacampus.fr, le cookie de session part quand même. On verra la parade en Partie 8 ; retiens ici le mécanisme.
L’origine : schéma + hôte + port
Le concept central de la sécurité navigateur est l’origine. Une origine est le triplet :
schéma :// hôte : port
https :// app.formacampus.fr : 443Deux URL ont la même origine si et seulement si les trois composants sont identiques. Un changement dans n’importe lequel crée une origine différente :
| URL A | URL B | Même origine ? | Pourquoi |
|---|---|---|---|
https://app.formacampus.fr/a | https://app.formacampus.fr/b | ✅ Oui | Seul le chemin diffère (hors origine). |
https://app.formacampus.fr | http://app.formacampus.fr | ❌ Non | Schéma différent (https vs http). |
https://app.formacampus.fr | https://api.formacampus.fr | ❌ Non | Hôte différent (sous-domaine). |
https://app.formacampus.fr | https://app.formacampus.fr:8443 | ❌ Non | Port différent. |
Le chemin, la query string et le fragment ne font pas partie de l’origine.
💡 Réflexe — Un piège fréquent : croire que deux sous-domaines du même site (
app.etapi.) sont « same-origin ». Non — l’hôte diffère, donc origines différentes. C’est pour ça qu’un front surapp.qui appelle une API surapi.a besoin de CORS (voir Partie 8). Ne confonds pas « même site » (même domaine enregistrable, notion utilisée parSameSite) et « même origine » (schéma+hôte+port identiques) : ce sont deux échelles distinctes.
La Same-Origin Policy (SOP)
La Same-Origin Policy est la règle de sécurité fondamentale des navigateurs. En substance : le code d’une origine ne peut pas lire les données d’une autre origine. Sans elle, n’importe quel site ouvert dans un onglet pourrait lire ton webmail, ta banque ou ton FormaCampus dans un autre onglet — le web serait inutilisable en sécurité.
Concrètement, la SOP fait qu’un script sur evil.example :
- peut envoyer une requête vers
app.formacampus.fr(l’envoi n’est pas bloqué)… - …mais ne peut pas lire la réponse (le résultat du
fetchcross-origin est masqué au JS, sauf si CORS l’autorise) ; - ne peut pas lire le contenu d’une
iframed’une autre origine, ni sondocument, ni ses cookies via JS ; - ne peut pas lire directement le DOM d’une autre origine.
Cette nuance — envoi possible, lecture bloquée — est essentielle :
- Elle explique pourquoi le CSRF existe : l’attaquant n’a pas besoin de lire la réponse, il lui suffit de déclencher une action (envoyer de l’argent, changer un email). L’envoi passe ; la SOP n’arrête pas l’effet de bord.
- Elle explique pourquoi le XSS est si grave : en injectant du code dans ton origine, l’attaquant contourne totalement la SOP — son code s’exécute comme s’il était toi, avec tous tes accès.
- Elle explique pourquoi CORS existe : c’est le mécanisme par lequel un serveur autorise explicitement certaines autres origines à lire ses réponses (assouplissement contrôlé de la SOP).
🎯 Côté attaquant — L’attaquant web passe son temps à contourner la SOP : soit en injectant son code dans ton origine (XSS → il devient toi), soit en exploitant le fait que l’envoi cross-origin reste possible (CSRF → il agit en ton nom sans lire), soit en profitant d’une config CORS trop permissive (le serveur autorise à tort son origine à lire). Comprendre la SOP, c’est comprendre ce que chaque grande attaque web cherche à faire sauter.
🧭 Sur FormaCampus — FormaCampus a un front sur
app.formacampus.fret une API surapi.formacampus.fr: origines différentes. Le front doit donc appeler l’API via CORS, configuré pour n’autoriser que l’originehttps://app.formacampus.fr(pas*), aveccredentialsmaîtrisés. Par ailleurs, l’équipe sait que la SOP n’empêche pas un site tiers de déclencher une requête authentifiée vers l’API : c’est pourquoi les actions sensibles sont aussi protégées contre le CSRF (Partie 8), en plus de CORS.
✏️ Exercices
Exercice 1 — Same-origin ou pas ? Pour chaque paire, dis si elle est same-origin : (a) https://formacampus.fr/cours et https://formacampus.fr/profil ; (b) https://formacampus.fr et https://www.formacampus.fr ; (c) http://localhost:3000 et http://localhost:5173.
✅ Solution
(a) Same-origin : schéma, hôte et port identiques, seul le chemin change. (b) Différentes : formacampus.fr et www.formacampus.fr sont des hôtes différents. (c) Différentes : même hôte mais ports différents (3000 vs 5173) — un piège fréquent en dev local, qui explique pourquoi le front Vite (5173) a besoin de CORS pour appeler une API sur 3000.
Exercice 2 — Que peut faire evil.example ? Un script sur evil.example veut nuire à un utilisateur connecté à app.formacampus.fr. Parmi ces actions, lesquelles la SOP empêche, lesquelles elle n’empêche pas : (a) envoyer un POST /api/supprimer-compte ; (b) lire le JSON renvoyé par GET /api/mes-donnees ; (c) lire les cookies de formacampus.fr via document.cookie.
✅ Solution
(a) Non empêché : l’envoi cross-origin est autorisé — le POST part, avec les cookies de session attachés par le navigateur. C’est exactement le mécanisme du CSRF (l’attaquant déclenche l’action sans lire la réponse) → il faut une protection CSRF dédiée. (b) Empêché : la SOP masque la réponse cross-origin au script (sauf CORS explicite). (c) Empêché : le script de evil.example ne peut pas lire document.cookie de formacampus.fr (autre origine) — et si les cookies sont HttpOnly, ils sont de toute façon invisibles au JS même same-origin.
🧠 Quiz de révision
1. De quoi est composée une « origine » ?
Du triplet schéma + hôte + port (ex. https + app.formacampus.fr + 443). Le chemin, la query string et le fragment n’en font pas partie. Deux URL sont same-origin ssi les trois composants sont identiques.
2. Que dit, en une phrase, la Same-Origin Policy ?
Le code d’une origine ne peut pas lire les données d’une autre origine. C’est l’isolation fondamentale qui empêche un site d’espionner les autres onglets.
3. La SOP empêche-t-elle un site d’envoyer une requête vers un autre ?
Non : l’envoi cross-origin reste possible ; c’est la lecture de la réponse qui est bloquée (sauf CORS). Cette nuance explique le CSRF (déclencher une action sans lire suffit).
4. Pourquoi le XSS est-il si grave au regard de la SOP ?
Parce qu’un XSS injecte du code dans ton origine : ce code s’exécute avec tous tes droits, contournant totalement la SOP. L’attaquant n’a plus besoin de la franchir — il est déjà « dedans ».
5. Peut-on faire confiance à l’en-tête Referer ou Origin pour une décision de sécurité ?
Referer ou Origin pour une décision de sécurité ?Avec prudence : ces en-têtes sont envoyés par le client et peuvent être absents ou falsifiés hors navigateur. Origin est utile comme défense supplémentaire anti-CSRF (le navigateur le pose de façon fiable pour les requêtes concernées), mais on ne base pas une autorisation sur un en-tête que le client contrôle. La confiance vient de la session validée côté serveur.
Chapitre suivant : Cookies & sessions — comment le navigateur mémorise ta connexion, et les trois attributs qui protègent (ou exposent) ta session.