Dans l’univers des applications web modernes, les requêtes HTTP sont au cœur de l’interaction navigateur / serveur. Mais ces mêmes requêtes peuvent aussi être exploitées par des attaquants pour réaliser des attaques comme le Cross-Site Request Forgery (CSRF).
Traditionnellement, défendre son application contre les attaques CSRF impliquait des jetons synchronisés, des vérifications d’origin ou des attributs SameSite sur les cookies. Aujourd’hui, les navigateurs modernes fournissent un nouvel ensemble d’en-têtes : les Fetch Metadata Request Headers (Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-Dest et Sec-Fetch-User) qui permettent au serveur de mieux comprendre le contexte de la requête et ainsi réduire considérablement l’exposition aux attaques CSRF.
Fetch Metadata : l’essentiel
Les Fetch Metadata Request Headers (“En-tête de métadonnées de requête de récupération” en Français) sont des en-têtes automatiquement ajoutés par les navigateurs pour contextualiser une requête HTTP :
Sec-Fetch-Site: indique la relation entre le site initiateur et le site ciblé (same-origin,same-site,cross-site,none) ;Sec-Fetch-Mode: décrit le mode de la requête (par exemplenavigate,cors,no-cors) ;Sec-Fetch-Dest: renseigne le type de ressource attendu (par exempledocument,image,script, …) ;Sec-Fetch-User: présent uniquement pour les requêtes initiées par une interaction de l’utilisateur (?1).
Ces en-têtes ne sont pas modifiables en JavaScript et ne peuvent être contrôlés par un site tiers malveillant, ce qui en fait des signaux fiables pour la politique de sécurité côté serveur.
Pourquoi ça compte pour le CSRF ?
Un attaque de type CSRF tente de faire effectuer à l’utilisateur authentifié une requête non désirée vers votre application depuis un site malveillant. Or, un navigateur envoie toujours automatiquement les cookies associés à votre domaine, même si la requête est déclenchée par un autre site. Sans protection, l’application backend reçoit une requête légitimement authentifiée par les cookies de session de l’utilisateur et souvent la traite.
L’idée des en-têtes fetch metadata est simple : un serveur peut discriminer quelles requêtes proviennent d’une navigation légitime du site propre (same-origin ou same-site) et rejeter celles qui sont forcément issues d’un autre site (cross-site).
Contrairement à l’en-tête Origin ou Referer, les en-têtes Sec-Fetch-* sont toujours présents et contrôlés par le navigateur, ce qui améliore la fiabilité de la décision serveur.
Comment bloquer les attaques de type CSRF
Voici une logique simple que vous pouvez appliquer côté backend (en Python par exemple avec Django) :
SAFE_METHODS = {"GET", "HEAD", "OPTIONS"}
# Ne s'applique qu'aux méthodes potentiellement dangereuses
if request.method not in SAFE_METHODS:
sec_fetch_site = (request.headers.get("Sec-Fetch-Site") or "").lower()
# Si c'est une requête cross-site, on refuse la requête
if sec_fetch_site == "cross-site":
return HttpResponseForbidden("Forbidden (Fetch Metadata / CSRF)")
Si la requête est cross-site, et elle tente une action potentiellement dangereuse (POST, PUT, DELETE, …) : la requête est refusée.
Les méthodes sûres (GET, HEAD, etc…) sont généralement autorisées, car elles ne modifient pas l’état serveur.
Vous pouvez ensuite affiner votre politique avec Sec-Fetch-Mode ou Sec-Fetch-Dest si nécessaire :
| En-tête | Utilité | Exemple d’usage |
|---|---|---|
Sec-Fetch-Site |
Relation entre origines | Bloquer toutes requêtes cross-site sur endpoints sensibles |
Sec-Fetch-Mode |
Type de requête | Autoriser uniquement navigate ou cors pour certains chemins |
Sec-Fetch-Dest |
Destination attendue | Assurer que des images/scripts ne sont pas utilisés pour POST sensibles |
Sec-Fetch-User |
Interaction utilisateur | Permettre certaines requêtes seulement si l’utilisateur a cliqué explicitement |
Bien que Sec-Fetch-Site soit le principal signal utilisé pour lutter contre les CSRF, il peut être combiné avec la validation de l’en-tête Origin là où certains navigateurs ne fourniraient pas ces en-têtes (navigateurs anciens notamment).
Limites & conseils pratiques
- Support navigateur : Tous les navigateurs modernes implémentent
Sec-Fetch-*. Pour les anciens, prévoyez une logique de repli (ex : vérification Origin). - Ne pas remplacer les jetons pour certaines applications critiques : ce mécanisme est très efficace, mais il peut être intéressant de le combiner à des protections classiques (jetons synchronisés, SameSite cookies, etc.) pour une défense en profondeur.
- Côté serveur uniquement : étant donné que les valeurs de ces en-têtes sont définies par le navigateur, le serveur est le seul endroit où elles doivent être interprétées.
Conclusion
Les en-têtes Fetch Metadata (Sec-Fetch-*) sont une avancée simple mais puissante pour durcir votre application contre les attaques CSRF sans modifier le code client, ni ajouter de lourdes synchronisations de jetons. En vérifiant d’où vient réellement une requête, vous donnez à votre serveur une signalisation fiable pour rejeter les attaques avant même qu’elles n’atteignent votre logique applicative.
C’est une couche complémentaire aux protections classiques (CORS, SameSite, jetons), qui s’intègre naturellement dans les architectures modernes.
Merci d'avoir lu cet article !
Si vous avez des commentaires ou des retours sur cet article, n'hésitez pas à me contacter. Venez aussi me dire bonjour sur X (ex-Twitter) ou sur Linkedin.