Introduction
Le CORS Cross-Origin Resource Sharing, a un impact sur le monitoring des performances. L’objectif de cet article est d’expliquer en quoi consiste le CORS, pourquoi il est utilisé, et son impact sur la façon dont vous pouvez surveiller les performances des services numériques.
Les applications web modernes utilisent massivement des ressources tierces. Il s’agit par exemple de l’utilisation de CDN pour mieux diffuser des contenus tels que des images et des feuilles de style, ou encore de ressources de services tiers qui sont appelées via des API. Ainsi, une page web peut être le résultat d’une multitude de requêtes adressées à différents hôtes appelés origines. Cela est particulièrement vrai pour les SPA (Single Page Applications) qui reposent principalement sur des appels à des backends via des API.
L’origine d’un contenu web est définie par le protocole, l’hôte (domaine) et le port de l’URL utilisé pour y accéder.
Ainsi, dès que le navigateur effectue des requêtes vers des origines différentes, le CORS entre en jeu.
Voyons pourquoi le CORS a un impact sur la supervision des performances.
Qu’est-ce que le CORS – Cross-Origin Resource Sharing ?
Le CORS est un mécanisme qui permet à un serveur de pointer toute autre origine que la sienne pour laquelle un navigateur doit autoriser le chargement de ressources.
En tant que tel, il s’agit principalement d’un mécanisme de sécurité appliqué par le serveur au niveau du navigateur. Il est utilisé pour autoriser les demandes faites au nom de l’utilisateur et, en même temps, pour bloquer certaines demandes faites par des JavaScripts potentiellement malveillants.
Avant la normalisation du CORS, tous les appels vers des origines externes (appels fetch ou ajax) étaient bloqués par la politique de même origine..
L’image suivante montre un exemple simple d’une page Web qui contient deux images et un peu de style.
La première requête HTTP GET (GET /
) détermine l’origine du contenu (domaine-a.com).
Le rendu correct de la page nécessite le téléchargement d’une feuille de style (layout.css) qui se trouve sur un service tiers via une requête d’origine croisée (domaine-b.com).
Enfin, une image (image-1) est stockée sur le serveur d’origine, tandis que la seconde (image-2) est stockée sur un troisième domaine (domaine-c.com).
Ainsi, dans ce petit exemple, l’obtention de la feuille de style ainsi que de l’image 2 est effectuée par des requêtes d’origine croisée.
Comment fonctionne le système CORS ?
Jusqu’à présent, vous avez vu qu’un serveur peut fournir au navigateur une liste d’origines à partir desquelles il peut demander du contenu. Le navigateur demande généralement ce contenu par des appels ajax ou fetch déclenchés par des JavaScripts.
Dans l’exemple précédent, les serveurs domain-b.com et domain-c.com doivent permettre au navigateur de récupérer des ressources initiées lors d’une précédente connexion au domain-a.com (par exemple, un JavaScript téléchargé depuis le serveur domain-a.com et exécuté sur le navigateur).
Mais comment un serveur accorde-t-il cette permission à un navigateur ?
Il le fait par le biais d’en-têtes HTTP (“headers”) spécifiques.
Le CORS dans les réponses HTTP
Le serveur accorde au navigateur la permission d’accéder à des ressources d’autres origines. Pour ce faire, il utilise l’en-tête HTTP Access-Control-Allow-Origin
Par exemple, vous pouvez autoriser la demande de ressources depuis n’importe quelle origine comme suit : Access-Control-Allow-Origin : *
Vous pouvez également vous limiter à une origine spécifique : Access-Control-Allow-Origin: https://example.com
Le CORS dans les requêtes HTTP
Il existe deux types de requêtes HTTP dans un contexte CORS : « simple » et « preflight ».
La requête « simple”
Dans l’exemple suivant, le client envoie une GET
equête GET à la page d’accueil du site Web exemple2.com.
Cette demande provient de l’adresse https://example.com, qui est spécifiée par l’en-tête de demande Origin
En réponse, le serveur renvoie un en-tête Access-Control-Allow-Origin
avec la valeur *
, ce qui signifie que la ressource est accessible par n’importe quelle origine.
La requête préalable “preflight”
Vous rencontrerez souvent ce type de requête lorsque le navigateur a l’intention d’utiliser des méthodes HTTP telles que PUT
, POST
ou DELETE
. Ces méthodes représentent évidemment un plus grand risque pour la sécurité car elles modifient généralement le contenu web sur le serveur.
Contrairement aux requêtes « simples », dans les requêtes « preflight », le navigateur envoie d’abord une requête HTTP en utilisant la méthode OPTION
pour déterminer si la requête réelle peut être envoyée en toute sécurité. En d’autres termes, cette demande de contrôle préalable vérifie si la requête principale est autorisée ou non.
Étant donné que la méthode OPTION
ne peut pas modifier la ressource elle-même, il s’agit d’une méthode sûre à utiliser.
Cet exemple montre le processus de base :
- Le client envoie une première requête de contrôle préalable en utilisant la méthode
POST
. Cette demande comprend, entre autres, les informations suivantes :- L’origine de la demande (https://example.com)
- La méthode HTTP que le navigateur utilisera dans la requête principale (
POST
comme mentionné par l’en-têteAccess-Control-Request-Method
) - L’en-tête HTTP que le navigateur utilisera dans la requête principale (X-PINGOTHER comme mentionné par l’en-tête
Access-Control-Request
header)
- Le serveur répond au navigateur en confirmant que la requête principale est autorisée. Pour cela, la réponse comprend les en-têtes suivants :
Access-Control-Allow-Origin
comme expliqué précédemment.Access-Control-Allow-Methods
qui fournit les types de méthodes HTTP qui seront autoriséesAccess-Control-Allow-Headers
qui fournit la liste des types d’en-têtes qui seront accessibles par la requête principale (X-PINGOTHER et Content-Type dans cet exemple)
- Sur la base de la réponse du contrôle préalable, le client exécute la requête principale
- Comme l’éligibilité de la requête a été vérifiée précédemment, le serveur envoie une réponse à cette requête principale. Notez que l’en-tête
Access-Control-Allow-Origin
est présent dans toutes les réponses du serveur.
Le site suivant fournit des codes pour implémenter le CORS sur différentes plateformes.
Qu’induit le CORS pour votre monitoring des performances ?
Maintenant que vous savez pourquoi le CORS existe et comment il fonctionne, examinons la façon dont les mesures de performance sont rapportées dans ce contexte.
Les principales solutions de monitoring des utilisateurs (trafic réel) utilisent du W3C comme base de collecte des mesures de performance :
L’article suivant fournit plus de détails sur le processus de chargement des pages.
Le problème que posent ici les ressources d’origine croisée est qu’elles n’exposent par défaut les horodatages que pour les attributs suivants :
- startTime (sera égal à fetchStart)
- fetchStart
- responseEnd
- durée
Cette mesure vise à protéger la vie privée des utilisateurs (afin qu’un attaquant ne puisse pas charger des URL aléatoires pour voir où vous avez été).
Cela signifie que tous les attributs suivants seront « Null » pour les ressources d’origine croisée :
- redirectStart
- redirectEnd
- domainLookupStart
- domainLookupEnd
- connectStart
- connectEnd
- secureConnectionStart
- requestStart
- responseStart
En outre, toutes les informations sur la taille seront « 0 » pour les ressources d’origine croisée :
- transferSize
- encodedBodySize
- decodedBodySize
Enfin, les ressources d’origine croisée qui sont redirigées auront une heure de début qui ne reflète que la ressource finale – startTime sera égal à fetchStart au lieu de redirectStart. Cela signifie que l’heure de toute(s) redirection(s) sera cachée dans la chronologie de la ressource.
Comme vous pouvez le constater, l’utilisation du CORS a un impact sur le contrôle des performances !
La solution pour surveiller les performances des ressources CORS : activer le TAO (Time-Allow-Origin)
Heureusement, si vous contrôlez les domaines à partir desquels vous récupérez d’autres ressources, vous pouvez contourner le mécanisme de protection par défaut en envoyant un en-tête Timing-Allow-Origin
dans les réponses HTTP, informant le navigateur qu’il est autorisé à traiter les mesures de performance.
Si vous diffusez votre contenu à partir d’un autre domaine, c’est-à-dire à partir d’un CDN, il est fortement recommandé de définir cet en-tête pour ces réponses. Heureusement, les bibliothèques tierces pour les widgets, les publicités, les analyses, etc., commencent à définir cet en-tête TAO pour leur contenu
En 2013, seulement 1,2 % du total des ressources intégrées sur quelques centaines de milliers de sites web présentaient l’en-tête TAO (Time Access Origin). En 2018, cela représentait environ15% du total des sites web. Il y a donc encore beaucoup de chemin à parcourir.
Enfin, si vous souhaitez toujours obtenir des mesures de performance à partir de l’API de Navigation Timing du W3C, il existe des extensions de navigateur qui permettent au navigateur de contourner toute restriction. Cela se fait évidemment au détriment de la sécurité ! Considérez donc cette solution de contournement comme une solution temporaire lorsque vous avez besoin de résoudre des dégradations spécifiques.
Vos prochaines étapes sur le suivi des performances CORS
Le CORS est un mécanisme de sécurité appliqué au niveau du navigateur. Si vous contrôlez les différents serveurs, assurez-vous d’autoriser les demandes d’origines croisées en ajoutant l’en-tête Access-Control-Allow-Origin
dans les réponses HTTP afin d’éviter les erreurs de récupération des ressources.
L’utilisation due CORS a un impact sur le suivi des performances. Le suivi des performances des requêtes d’origine croisée est un défi car les mesures ne sont pas collectées par défaut.
Si vous utilisez des services de tiers comme les CDN, assurez-vous qu’ils vous permettent d’activer l’en-tête Timing-Allow-Origin
dans les réponses HTTP.
Si cela n’est pas possible mais que vous avez vraiment besoin de collecter ces mesures de performance, activez temporairement les extensions spécialisées du navigateur qui désactivent cette protection de sécurité.