La norme CORS : gestion du partage de ressources entre origines multiples

Le mécanisme CORS pour « Content Origin Resource Sharing » ou « Partage de Ressources entre Origines Multiples » permet la récupération de ressources choisies à partir d’origines différentes de la cible de la requête.

Lorsqu’on crée un site, il va être courant d’utiliser des ressources appartenant à d’autres sites dans nos propres pages. Cela va être notamment le cas lors de l’utilisation (et donc du chargement) d’une police d’écriture Google, d’une feuille de style externe comme un fichier CSS Bootstrap ou encore lors de l’inclusion d’un script JavaScript externe comme cela va être le cas si vous implémentez des solutions comme Google Analytics ou Google Adsense.

La problématique ici est qu’il peut être très dangereux pour un visiteur de télécharger des ressources à partir d’une autre source que celle qui est la cible de sa requête. En effet, sans restriction ni contrôle, un client pourrait aussi bien télécharger aveuglément du code malveillant et être piraté.

Conscients de cela, la plupart des clients (navigateurs) suivent des politiques de sécurité pour atténuer ces risques et notamment la politique dite de même origine ou « same-origin policy » en anglais.

 

La politique de même origine ou same-origin policy

La politique de même origine stipule qu’un document hébergé sur un serveur ne peut interagir qu’avec d’autres documents possédant la même origine.

Une origine est composée d’un protocole, d’un hôte et d’un numéro de port. Deux documents ont la même origine si le protocole, l’hôte et le numéro de port sont les mêmes.

  • Le protocole : sur le web, les protocoles utilisés pour accéder à un document vont généralement être HTTP et HTTPS ;
  • Le nom d’hôte : c’est ce qu’on appelle également le nom de domaine. Attention, un sous domaine sera considéré comme un nom d’hôte différent ;
  • Le numéro de port : spécifie le port utilisé pour se connecter. HTTP utilise le port 80 par défaut, HTTPS utilise le port 443 par défaut. Si il est précisé, il doit correspondre pour satisfaire à la condition de même origine.

Imaginons un premier document situé à l’adresse http://www.pierre-giraud.com/home.html qui cherche à récupérer une ressource située à une autre adresse. Regardons ce que ce document est autorisé à récupérer en respectant la politique de même origine :

URL de la ressourceRésultatExplication
http://www.pierre-giraud.com/cours.htmlSuccès
https://www.pierre-giraud.com/cours.htmlEchecProtocoles (et numéro de port) différents
http://www.cours.pierre-giraud.com/index.htmlEchecHôtes différents
http://www.wikipedia.org/index.htmlEchecHôtes différents
http://www.pierre-giraud.com:88/cours.htmlEchecPorts différents

Comme vous pouvez le voir, la politique de même origine est extrêmement restrictive puisqu’elle interdit tout simplement de faire appel à des ressources d’origine différente. Pour autant, ne pas implémenter de politique de sécurité rendrait le Web bien trop risqué. C’est la raison pour laquelle la norme CORS a été créée.

 

Qu’est-ce que CORS ?

Le partage de ressources entre origines multiples intervient lorsqu’un document inclut une demande de ressources située à une autre origine.

Si toutes les demandes de ressources à partir d’une autre origine étaient interdites, le Web serait très limité et beaucoup moins performant.

Le mécanisme CORS permet aux serveurs de spécifier qui (c’est-à-dire quelles origines) peut accéder aux ressources sur le serveur ainsi que la façon dont on va pouvoir y accéder.

Concrètement, la plupart des serveurs vont autoriser les requêtes dites « safe », c’est-à-dire les requêtes qui ne modifient pas les ressources sur le serveur comme GET et vont donc permettre aux ressources d’origine externe d’accéder à leurs ressources en lecture simple.

En revanche, d’autres méthodes dits « unsafe » comme PUT ou DELETE peuvent être refusées pour empêcher tout comportement malveillant : il est légitime qu’un serveur ne souhaite pas que d’autres serveurs modifient ou suppriment ses ressources.

Cependant, les serveurs ne bloquent pas systématiquement de telles requêtes. Pour être tout à fait précis, la norme CORS impose aux navigateurs d’effectuer un contrôle en amont des requêtes (« preflight request ») pour les méthodes de requêtes qui peuvent modifier les données avant d’envoyer la requête réelle dans le cas où le serveur l’approuverait.

Concrètement, les requêtes en amont consistent en l’envoi préalable d’une requête HTTP avec la méthode OPTIONS à la ressource cross-origin pour déterminer si la requête réelle peut être envoyée en toute sécurité.

 

Comment fonctionne CORS en pratique ?

La norme CORS gère les demandes d’origine croisée en ajoutant de nouveaux en-têtes HTTP à la liste standard des en-têtes. Ces en-têtes sont les suivants :

  • Access-Control-Allow-Origin : indique si la réponse peut être partagée, en renvoyant la valeur littérale de l’en-tête de requête Origin (qui peut être « null ») ou « * » dans une réponse. ;
  • Access-Control-Allow-Credentials : indique si la réponse peut être partagée lorsque le mode d’informations d’identification de la requête est « include » ;
  • Access-Control-Allow-Headers: indique les en-têtes pris en charge par l’URL de la réponse aux fins du protocole CORS ;
  • Access-Control-Allow-Methods : indique les méthodes prises en charge par l’URL de la réponse aux fins du protocole CORS : indique quels en-têtes peuvent être exposés dans la réponse en répertoriant leurs noms ;
  • Access-Control-Expose-Headers : indique quels en-têtes peuvent être exposés dans le cadre de la réponse en répertoriant leurs noms ;
  • Access-Control-Max-Age: indique le nombre de secondes (5 par défaut) pendant lesquelles les informations fournies par les en-têtes Access-Control-Allow-Methods et Access-Control-Allow-Headers peuvent être mises en cache ;
  • Access-Control-Request-Headers : indique les en-têtes qu’une future requête CORS à la même ressource pourrait utiliser ;
  • Access-Control-Request-Method : indique la méthode qu’une future requête CORS à la même ressource pourrait utiliser ;
  • Origin : indique d’où provient une récupération (un fetch).

 

En résumé : quel intérêt de mettre en place CORS

Aujourd’hui, de plus en plus de sites font appel à des ressources externes. Pour se protéger contre le téléchargement de code potentiellement malveillant, les navigateurs et les serveurs mettent en place des politique de sécurité dont la politique de même origine qui est très restrictive.

Le mécanisme CORS est un mécanisme qui utilise des en-têtes HTTP supplémentaires pour indiquer aux navigateurs quels types de requêtes doivent être acceptées et quelles autres doivent être rejetées et à quelles conditions.

Au final, CORS définit une manière dont un navigateur et un serveur peuvent interagir pour déterminer si une requête pour une ressource située à une autre origine doit être autorisée ou pas.

© Pierre Giraud - Toute reproduction interdite