Protégez vos ressources contre les attaques sur le Web avec Fetch Metadata

Évitez les fuites d'informations CSRF, XSSI et d'informations multi-origines.

Pourquoi est-il important d'isoler vos ressources Web ?

De nombreuses applications Web sont vulnérables aux attaques cross-origin, telles que la falsification de requête intersites (CSRF), l'inclusion de scripts intersites (XSSI), les attaques temporelles, les fuites d'informations multi-origines ou les attaques par canal auxiliaire d'exécution spéculative (Spectre).

Les en-têtes de requête Fetch Metadata vous permettent de déployer un mécanisme de défense en profondeur robuste (un règlement d'isolation des ressources) pour protéger votre application contre ces attaques multi-origines courantes.

Il est courant que les ressources exposées par une application Web donnée ne soient chargées que par l'application elle-même, et non par d'autres sites Web. Dans ce cas, le déploiement d'une règle d'isolation des ressources basée sur les en-têtes de requête Fetch Metadata demande peu d'efforts et, dans le même temps, protège l'application contre les attaques intersites.

Compatibilité du navigateur

Les en-têtes de requête Fetch Metadata sont compatibles avec tous les moteurs de navigateur modernes.

Navigateurs pris en charge

  • Chrome: 76 <ph type="x-smartling-placeholder">
  • Edge: 79 <ph type="x-smartling-placeholder">
  • Firefox: 90 <ph type="x-smartling-placeholder">
  • Safari: 16.4. <ph type="x-smartling-placeholder">

Source

Contexte

De nombreuses attaques intersites sont possibles, car le Web est ouvert par défaut et votre serveur d'applications ne peut pas facilement se protéger des communications provenant d'applications externes. Une attaque multi-origine typique est une falsification de requête intersites (CSRF) : un pirate informatique attire un utilisateur sur un site qu'il contrôle, puis envoie un formulaire au serveur auquel l'utilisateur est connecté. Étant donné que le serveur ne peut pas déterminer si la requête provient d'un autre domaine (intersites) et que le navigateur associe automatiquement des cookies aux requêtes intersites, le serveur exécute l'action demandée par le pirate informatique au nom de l'utilisateur.

D'autres attaques intersites telles que l'inclusion de scripts intersites (XSSI) ou les fuites d'informations multi-origines sont de nature similaire au CSRF et reposent sur le chargement de ressources à partir d'une application victime dans un document contrôlé par le pirate et la fuite d'informations sur les applications de la victime. Les applications ne pouvant pas distinguer facilement les requêtes approuvées de celles qui ne le sont pas, elles ne peuvent pas supprimer le trafic intersites malveillant.

Présentation de la récupération de métadonnées

Les en-têtes de requête Fetch Metadata sont une nouvelle fonctionnalité de sécurité de la plate-forme Web conçue pour aider les serveurs à se défendre contre les attaques multi-origines. En fournissant des informations sur le contexte d'une requête HTTP dans un ensemble d'en-têtes Sec-Fetch-*, elles permettent au serveur qui répond d'appliquer des règles de sécurité avant de traiter la requête. Les développeurs peuvent ainsi décider d'accepter ou de refuser une demande en fonction de la manière dont elle a été envoyée et du contexte dans lequel elle sera utilisée. Ils peuvent ainsi répondre uniquement aux demandes légitimes de leur propre application.

Même origine
<ph type="x-smartling-placeholder"></ph> Les requêtes provenant de sites gérés par votre propre serveur (de même origine) continueront de fonctionner. Si une requête de récupération de la ressource https://site.example/foo.json provient de https://site.example en JavaScript, le navigateur envoie l&#39;en-tête de requête HTTP &quot;Sec Fetch-Site: same-origin&quot;.
Intersites
<ph type="x-smartling-placeholder"></ph> Les requêtes intersites malveillantes peuvent être rejetées par le serveur en raison du contexte supplémentaire fourni par les en-têtes Sec-Fetch-* dans la requête HTTP. Image sur https://evil.example qui a défini l&#39;attribut src d&#39;un élément img sur &quot;https://site.example/foo.json&quot; le navigateur envoie l&#39;en-tête de requête HTTP &quot;Sec-Fetch-Site: inter-site&quot;.

Sec-Fetch-Site

Navigateurs pris en charge

  • Chrome: 76 <ph type="x-smartling-placeholder">
  • Edge: 79 <ph type="x-smartling-placeholder">
  • Firefox: 90 <ph type="x-smartling-placeholder">
  • Safari: 16.4. <ph type="x-smartling-placeholder">

Source

Sec-Fetch-Site indique au serveur le site qui a envoyé la requête. Le navigateur définit cette valeur sur l'une des valeurs suivantes:

  • same-origin, si la requête a été effectuée par votre propre application (par exemple, site.example)
  • same-site, si la demande a été effectuée par un sous-domaine de votre site (par exemple, bar.site.example)
  • none, si la requête a été explicitement provoquée par une interaction de l'utilisateur avec le user-agent (par exemple, un clic sur un favori).
  • cross-site, si la requête a été envoyée par un autre site Web (par exemple, evil.example)

Sec-Fetch-Mode

Navigateurs pris en charge

  • Chrome: 76 <ph type="x-smartling-placeholder">
  • Edge: 79 <ph type="x-smartling-placeholder">
  • Firefox: 90 <ph type="x-smartling-placeholder">
  • Safari: 16.4. <ph type="x-smartling-placeholder">

Source

Sec-Fetch-Mode indique le mode de la requête. Cela correspond approximativement au type de requête et vous permet de distinguer les charges de ressources des requêtes de navigation. Par exemple, la destination navigate indique une requête de navigation de premier niveau, tandis que no-cors indique des demandes de ressources telles que le chargement d'une image.

Sec-Fetch-Dest

Navigateurs pris en charge

  • Chrome: 80 <ph type="x-smartling-placeholder">
  • Edge: 80 <ph type="x-smartling-placeholder">
  • Firefox: 90 <ph type="x-smartling-placeholder">
  • Safari: 16.4. <ph type="x-smartling-placeholder">

Source

Sec-Fetch-Dest expose la destination d'une requête (par exemple, si un tag script ou img a entraîné la requête d'une ressource par le navigateur).

Utiliser Fetch Metadata pour se protéger contre les attaques d'origine croisée

Les informations supplémentaires fournies par ces en-têtes de requête sont assez simples, mais le contexte supplémentaire vous permet de créer une logique de sécurité puissante côté serveur, également appelée règle d'isolation des ressources, avec seulement quelques lignes de code.

Implémenter une règle d'isolation de ressources

Une règle d'isolation des ressources empêche les sites Web externes de demander vos ressources. Le blocage de ce type de trafic réduit les failles Web intersites courantes telles que CSRF, XSSI, les attaques temporelles et les fuites d'informations multi-origines. Cette règle peut être activée pour tous les points de terminaison de votre application et autorisera toutes les requêtes de ressources provenant de votre propre application, ainsi que les navigations directes (via une requête HTTP GET). Les points de terminaison censés être chargés dans un contexte intersites (par exemple, les points de terminaison chargés à l'aide de CORS) peuvent être désactivés dans cette logique.

Étape 1: Autorisez les requêtes provenant des navigateurs qui n'envoient pas de métadonnées de récupération

Étant donné que tous les navigateurs ne sont pas compatibles avec l'extraction des métadonnées, vous devez autoriser les requêtes qui ne définissent pas d'en-têtes Sec-Fetch-* en vérifiant la présence de sec-fetch-site.

if not req['sec-fetch-site']:
  return True  # Allow this request

Étape 2: Autorisez les requêtes lancées sur un même site ou par un navigateur

Toutes les requêtes qui ne proviennent pas d'un contexte multi-origine (comme evil.example) seront autorisées. Il s'agit en particulier de requêtes qui:

  • proviennent de votre propre application (par exemple, une requête de même origine pour laquelle les requêtes site.example site.example/foo.json seront toujours autorisées).
  • proviennent de vos sous-domaines ;
  • sont explicitement dues à une interaction de l'utilisateur avec le user-agent (par exemple, en cas de navigation directe ou de clic sur un favori).
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
  return True  # Allow this request

Étape 3: Autorisez la navigation de premier niveau et les cadres iFrame simples

Pour que votre site puisse toujours être lié à d'autres sites, vous devez autoriser la navigation de premier niveau simple (HTTP GET).

if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
  # <object> and <embed> send navigation requests, which we disallow.
  and req['sec-fetch-dest'] not in ('object', 'embed'):
    return True  # Allow this request

Étape 4: Désactivez les points de terminaison destinés à diffuser du trafic intersites (facultatif)

Dans certains cas, votre application peut fournir des ressources destinées à être chargées sur plusieurs sites. Ces ressources doivent être exemptées pour chaque chemin d'accès ou point de terminaison. Exemples de points de terminaison de ce type:

  • Points de terminaison destinés à être accessibles multi-origines: si votre application diffuse des points de terminaison pour lesquels CORS est activé, vous devez les désactiver explicitement de l'isolation des ressources pour vous assurer que les requêtes intersites adressées à ces points de terminaison sont toujours possibles.
  • Ressources publiques (images, styles, etc.): Toutes les ressources publiques et non authentifiées qui doivent pouvoir être chargées en multi-origine à partir d'autres sites peuvent également être exemptées.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
  return True

Étape 5: Refusez toutes les autres demandes intersites et non liées à la navigation

Toute autre requête intersite sera rejetée par ce règlement d'isolation des ressources, et protégera ainsi votre application contre les attaques intersites courantes.

Exemple:Le code suivant illustre l'implémentation complète d'une stratégie d'isolation des ressources robuste sur le serveur ou en tant que middleware pour refuser les demandes de ressources intersites potentiellement malveillantes, tout en permettant de simples requêtes de navigation:

# Reject cross-origin requests to protect from CSRF, XSSI, and other bugs
def allow_request(req):
  # Allow requests from browsers which don't send Fetch Metadata
  if not req['sec-fetch-site']:
    return True

  # Allow same-site and browser-initiated requests
  if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
    return True

  # Allow simple top-level navigations except <object> and <embed>
  if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
    and req['sec-fetch-dest'] not in ('object', 'embed'):
      return True

  # [OPTIONAL] Exempt paths/endpoints meant to be served cross-origin.
  if req.path in ('/my_CORS_endpoint', '/favicon.png'):
    return True

  # Reject all other requests that are cross-site and not navigational
  return False

Déployer une règle d'isolation de ressources

  1. Installez un module comme l'extrait de code ci-dessus pour enregistrer et surveiller le comportement de votre site. Assurez-vous également que les restrictions n'affectent pas le trafic légitime.
  2. Corrigez les cas de non-respect potentiels en exemptant des points de terminaison multi-origine légitimes.
  3. Appliquez la règle en supprimant les requêtes non conformes.

Identifier et corriger les cas de non-respect des règles

Nous vous recommandons de tester votre stratégie sans effets secondaires en l'activant d'abord en mode de création de rapports dans votre code côté serveur. Vous pouvez également implémenter cette logique dans un middleware ou dans un proxy inverse qui enregistre tous les cas de non-respect que votre règle pourrait générer lorsqu'elle est appliquée au trafic de production.

D'après notre expérience de déploiement d'une règle d'isolation des ressources de récupération des métadonnées chez Google, la plupart des applications sont compatibles par défaut avec ce type de règle et nécessitent rarement des points de terminaison exemptés pour autoriser le trafic intersites.

Appliquer une règle d'isolation des ressources

Après avoir vérifié que vos règles n'ont aucune incidence sur le trafic de production légitime, vous pouvez appliquer des restrictions afin de garantir que les autres sites ne pourront pas demander vos ressources et de protéger vos utilisateurs contre les attaques intersites.

Documentation complémentaire