Qu'est-ce que CORS ?
Les navigateurs appliquent des règles strictes pour protéger les ressources. Par défaut, ils bloquent l’accès aux ressources provenant d’une origine différente (un domaine, un port ou un protocole différent), ce qui peut entraîner des erreurs telles que : Access to fetch at "origin différente" from origin "votre origine" has been blocked by CORS policy.
Pour contourner ces restrictions, les navigateurs utilisent un mécanisme appelé CORS (Cross-Origin Resource Sharing). Ce système permet d’autoriser le partage de ressources entre différentes origines en ajoutant des en-têtes de réponse tels que Access-Control-Allow-Origin, Access-Control-Allow-Headers et Access-Control-Allow-Credentials.
Cependant, cette politique ne s’applique pas aux ressources telles que les fichiers CSS, JavaScript ou images. En revanche, les requêtes HTTP effectuées depuis des scripts, par exemple avec XMLHttpRequest ou l’API Fetch, sont bloquées si elles ne respectent pas la politique de même origine.
La politique CORS est spécifique aux navigateurs web. Ainsi, lorsque vous effectuez des requêtes depuis des applications mobiles ou des outils comme Postman, vous ne serez pas soumis à ces restrictions, car celles-ci sont conçues pour protéger les interactions entre le navigateur et les serveurs web.
Pourquoi les navigateurs ont conçu le mécanisme CORS ?
Protection contre les attaques Cross-Site Scripting (XSS)
Les attaques XSS permettent à des attaquants d’injecter du code malveillant dans des pages web, ce qui peut entraîner le vol d’informations sensibles telles que des cookies ou des jetons d’authentification.
En restreignant les requêtes entre origines différentes, le mécanisme CORS limite la capacité des scripts malveillants à accéder aux données d’un site différent de celui d’où ils ont été chargés.
Prévention des attaques Cross-Site Request Forgery (CSRF)
Les attaques CSRF exploitent la confiance qu’un site web accorde au navigateur de l’utilisateur pour envoyer des requêtes non autorisées. CORS aide à prévenir ces attaques en limitant les requêtes HTTP entre différents sites web, réduisant ainsi les risques d’exécution de requêtes non autorisées sur des sites web tiers.
Contrôle granulaire des ressources partagées
CORS permet aux développeurs de concevoir des applications web plus sécurisées et robustes en offrant un contrôle détaillé sur le partage des ressources entre différentes origines. Cette fonctionnalité est cruciale pour préserver l’intégrité et la confidentialité des données.
Comment configurer les CORS ?
Les erreurs CORS (Cross-Origin Resource Sharing) se produisent lorsque vous tentez d’effectuer une requête HTTP vers un domaine différent de celui d’où provient votre page web. Normalement, vous devez configurer le serveur cible pour autoriser les requêtes provenant de votre domaine en ajoutant les en-têtes CORS appropriés
Access-Control-Allow-Origin
L'en-tête de réponse Access-Control-Allow-Origin
permet de spécifier quelles origines sont autorisées à accéder aux ressources. Il peut prendre plusieurs valeurs :
*
: Autorise toutes les origines.https://exemple.fr
: Autorise uniquement le domaine spécifié à accéder aux ressources.
Si vous devez autoriser plusieurs domaines, vous ne pouvez pas simplement les lister dans un seul en-tête. Dans ce cas, il est recommandé de vérifier l’origine de chaque requête. Si l’origine est autorisée, définissez-la dynamiquement dans l’en-tête Access-Control-Allow-Origin
avant d'envoyer la réponse.
$allowedOrigins = ['https://exemple.fr', 'https://autre-exemple.fr'];
if (isset($_SERVER['HTTP_ORIGIN']) && in_array($_SERVER['HTTP_ORIGIN'], $allowedOrigins, true)) {
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
}
Access-Control-Allow-Headers
L'en-tête de réponse Access-Control-Allow-Origin
suffit pour les requêtes simples. Une requête est considérée comme simple si elle répond à certains critères :
- La méthode est
GET
,POST
ouHEAD
. - Les en-têtes paramétrables sont limités à
Accept
,Accept-Language
,Content-Language
etContent-Type
. - Le
Content-Type
est limité aux valeurs suivantes :application/x-www-form-urlencoded
,multipart/form-data
outext/plain
.
Par exemple, lorsque les données sont envoyées au format JSON, ce qui entraîne l'utilisation de Content-Type: application/json
, cela ne constitue plus une requête simple. Le navigateur effectuera alors une requête préliminaire (preflight request) de type OPTIONS
pour vérifier si le serveur accepte les requêtes avec ces en-têtes avant d’envoyer la requête principale. Cela peut générer des erreurs CORS comme :
Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
Dans ce cas, vous devez ajouter un en-tête de réponse Access-Control-Allow-Headers
pour spécifier les en-têtes autorisés lors de l’envoi de la requête principale :
header("Access-Control-Allow-Headers: Accept, Content-Type");
Access-Control-Allow-Methods
De même, lors d’une requête préliminaire, vous pouvez spécifier une ou plusieurs méthodes autorisées lors de l’accès à une ressource :
header("Access-Control-Allow-Methods: GET, POST");
Access-Control-Allow-Credentials
Si vous souhaitez partager des cookies ou des informations d'authentification entre deux domaines via fetch
, XMLHttpRequest
ou EventSource
, vous devez définir l'en-tête de réponse Access-Control-Allow-Credentials
à true
. Cela indique au navigateur que le serveur autorise l'inclusion de ces informations dans les requêtes.
Que faire si vous n'avez pas accès au serveur pour configurer les en-têtes CORS ?
Si vous ne pouvez pas modifier la configuration du serveur cible, une solution consiste à mettre en place un proxy. L’idée est de rediriger la requête vers votre propre serveur (sur le même domaine que votre frontend), lequel transmettra ensuite la requête au serveur distant. De cette façon, le navigateur perçoit la requête comme provenant du même domaine, ce qui évite les restrictions CORS.
Pour les développeurs de Symfony, vous pouvez installer le bundle Nelmio CORS.
Pour les développeurs de Laravel, les versions antérieures à 9.2 nécessitent l'installation du middleware Fruitcake Laravel CORS. Pour les versions 9.2 et supérieures, le middleware est inclus directement dans le framework.
Aucune page ou chapitre n'a été ajouté à cet article.