CORS - Misconfigurations & Bypass
Qu'est-ce que CORS?
La norme Cross-Origin Resource Sharing (CORS) permet aux serveurs de définir qui peut accéder à leurs ressources et quelles méthodes de requête HTTP sont autorisées à partir de sources externes.
Une politique de même origine exige qu'un serveur demandant une ressource et le serveur hébergeant la ressource partagent le même protocole (par exemple, http://
), nom de domaine (par exemple, internal-web.com
), et port (par exemple, 80). Selon cette politique, seules les pages web du même domaine et port sont autorisées à accéder aux ressources.
L'application de la politique de même origine dans le contexte de http://normal-website.com/example/example.html
est illustrée comme suit:
http://normal-website.com/example/
Oui: Schéma, domaine et port identiques
http://normal-website.com/example2/
Oui: Schéma, domaine et port identiques
https://normal-website.com/example/
Non: Schéma et port différents
http://en.normal-website.com/example/
Non: Domaine différent
http://www.normal-website.com/example/
Non: Domaine différent
http://normal-website.com:8080/example/
Non: Port différent*
*Internet Explorer ignore le numéro de port dans l'application de la politique de même origine, permettant ainsi cet accès.
En-tête Access-Control-Allow-Origin
Access-Control-Allow-Origin
Cet en-tête peut autoriser plusieurs origines, une valeur null
, ou un joker *
. Cependant, aucun navigateur ne prend en charge plusieurs origines, et l'utilisation du joker *
est soumise à des limitations. (Le joker doit être utilisé seul, et son utilisation avec Access-Control-Allow-Credentials: true
n'est pas autorisée.)
Cet en-tête est émis par un serveur en réponse à une requête de ressource entre domaines initiée par un site web, le navigateur ajoutant automatiquement un en-tête Origin
.
En-tête Access-Control-Allow-Credentials
Access-Control-Allow-Credentials
Par défaut, les requêtes entre domaines sont effectuées sans informations d'identification telles que les cookies ou l'en-tête d'autorisation. Cependant, un serveur entre domaines peut autoriser la lecture de la réponse lorsque des informations d'identification sont envoyées en définissant l'en-tête Access-Control-Allow-Credentials
sur true
.
Si défini sur true
, le navigateur transmettra les informations d'identification (cookies, en-têtes d'autorisation ou certificats client TLS).
Requête de pré-vol CSRF
Comprendre les requêtes de pré-vol dans la communication inter-domaines
Lors de l'initiation d'une requête inter-domaines dans des conditions spécifiques, telles que l'utilisation d'une méthode HTTP non standard (autre que HEAD, GET, POST), l'introduction de nouveaux en-têtes, ou l'utilisation d'une valeur spéciale d'en-tête Content-Type, une requête de pré-vol peut être nécessaire. Cette requête préliminaire, utilisant la méthode OPTIONS
, sert à informer le serveur des intentions de la future requête inter-origines, y compris les méthodes HTTP et les en-têtes qu'elle a l'intention d'utiliser.
Le protocole Cross-Origin Resource Sharing (CORS) impose cette vérification de pré-vol pour déterminer la faisabilité de l'opération inter-origines demandée en vérifiant les méthodes autorisées, les en-têtes et la fiabilité de l'origine. Pour une compréhension détaillée des conditions qui contournent le besoin d'une requête de pré-vol, consultez le guide complet fourni par Mozilla Developer Network (MDN).
Il est crucial de noter que l'absence d'une requête de pré-vol n'élimine pas l'obligation pour la réponse de contenir des en-têtes d'autorisation. Sans ces en-têtes, le navigateur est incapable de traiter la réponse de la requête inter-origines.
Considérez l'illustration suivante d'une requête de pré-vol visant à utiliser la méthode PUT
avec un en-tête personnalisé nommé Special-Request-Header
:
En réponse, le serveur pourrait renvoyer des en-têtes indiquant les méthodes acceptées, l'origine autorisée et d'autres détails de la politique CORS, comme indiqué ci-dessous:
Access-Control-Allow-Headers
: Ce header spécifie les en-têtes qui peuvent être utilisés lors de la requête réelle. Il est défini par le serveur pour indiquer les en-têtes autorisés dans les requêtes du client.Access-Control-Expose-Headers
: À travers ce header, le serveur informe le client des en-têtes qui peuvent être exposés en plus des en-têtes de réponse simples.Access-Control-Max-Age
: Ce header indique pendant combien de temps les résultats d'une requête pré-vol peuvent être mis en cache. Le serveur définit le temps maximum, en secondes, pendant lequel les informations renvoyées par une requête pré-vol peuvent être réutilisées.Access-Control-Request-Headers
: Utilisé dans les requêtes pré-vol, ce header est défini par le client pour informer le serveur des en-têtes HTTP que le client souhaite utiliser dans la requête réelle.Access-Control-Request-Method
: Ce header, également utilisé dans les requêtes pré-vol, est défini par le client pour indiquer la méthode HTTP qui sera utilisée dans la requête réelle.Origin
: Ce header est automatiquement défini par le navigateur et indique l'origine de la requête entre domaines. Il est utilisé par le serveur pour évaluer si la requête entrante doit être autorisée ou refusée en fonction de la politique CORS.
Notez qu'en général (selon le type de contenu et les en-têtes définis), dans une requête GET/POST, aucune requête pré-vol n'est envoyée (la requête est envoyée directement), mais si vous souhaitez accéder aux en-têtes/corps de la réponse, elle doit contenir un en-tête Access-Control-Allow-Origin le permettant. Par conséquent, CORS ne protège pas contre les CSRF (mais peut être utile).
Requête pré-vol pour les demandes du réseau local
Access-Control-Request-Local-Network
: Ce header est inclus dans la requête du client pour indiquer que la demande est destinée à une ressource du réseau local. Il sert de marqueur pour informer le serveur que la demande provient du réseau local.Access-Control-Allow-Local-Network
: En réponse, les serveurs utilisent ce header pour communiquer que la ressource demandée est autorisée à être partagée avec des entités en dehors du réseau local. Il agit comme un feu vert pour le partage de ressources à travers différentes frontières réseau, assurant un accès contrôlé tout en maintenant les protocoles de sécurité.
Une réponse valide autorisant la demande du réseau local doit également contenir dans la réponse l'en-tête Access-Controls-Allow-Local_network: true
:
Notez que l'IP linux 0.0.0.0 fonctionne pour contourner ces exigences afin d'accéder à localhost car cette adresse IP n'est pas considérée comme "locale".
Il est également possible de contourner les exigences du réseau local si vous utilisez l'adresse IP publique d'un point de terminaison local (comme l'adresse IP publique du routeur). Car dans plusieurs cas, même si l'adresse IP publique est utilisée, si c'est à partir du réseau local, l'accès sera autorisé.
Configurations mal sécurisées exploitables
Il a été observé que le paramétrage de Access-Control-Allow-Credentials
à true
est une condition préalable pour la plupart des attaques réelles. Ce paramètre permet au navigateur d'envoyer des informations d'identification et de lire la réponse, améliorant ainsi l'efficacité de l'attaque. Sans cela, l'avantage de faire émettre une requête par un navigateur plutôt que de le faire soi-même diminue, car l'exploitation des cookies d'un utilisateur devient irréalisable.
Exception : Exploitation de la localisation réseau comme authentification
Une exception existe lorsque la localisation réseau de la victime agit comme une forme d'authentification. Cela permet à un navigateur de la victime d'être utilisé comme proxy, contournant l'authentification basée sur l'IP pour accéder aux applications intranet. Cette méthode présente des similitudes d'impact avec le rebinding DNS mais est plus simple à exploiter.
Réflexion de Origin
dans Access-Control-Allow-Origin
Origin
dans Access-Control-Allow-Origin
Le scénario réel où la valeur de l'en-tête Origin
est reflétée dans Access-Control-Allow-Origin
est théoriquement improbable en raison des restrictions sur la combinaison de ces en-têtes. Cependant, les développeurs cherchant à activer CORS pour plusieurs URL peuvent générer dynamiquement l'en-tête Access-Control-Allow-Origin
en copiant la valeur de l'en-tête Origin
. Cette approche peut introduire des vulnérabilités, en particulier lorsque qu'un attaquant utilise un domaine avec un nom conçu pour sembler légitime, trompant ainsi la logique de validation.
Exploitation de l'origine null
null
L'origine null
, spécifiée pour des situations telles que les redirections ou les fichiers HTML locaux, occupe une position unique. Certaines applications ajoutent cette origine à leur liste blanche pour faciliter le développement local, permettant involontairement à n'importe quel site web de simuler une origine null
via un iframe sandboxé, contournant ainsi les restrictions CORS.
Techniques de Contournement des Expressions Régulières
Lorsqu'on rencontre une liste blanche de domaines, il est crucial de tester les opportunités de contournement, telles que l'ajout du domaine de l'attaquant à un domaine autorisé ou l'exploitation des vulnérabilités de prise de contrôle de sous-domaine. De plus, les expressions régulières utilisées pour la validation de domaine peuvent négliger les subtilités des conventions de nommage de domaine, offrant ainsi d'autres opportunités de contournement.
Contournements Avancés des Expressions Régulières
Les modèles Regex se concentrent généralement sur les caractères alphanumériques, le point (.), et le tiret (-), en négligeant d'autres possibilités. Par exemple, un nom de domaine conçu pour inclure des caractères interprétés différemment par les navigateurs et les modèles Regex peut contourner les vérifications de sécurité. La manière dont Safari, Chrome et Firefox gèrent les caractères de soulignement dans les sous-domaines illustre comment de telles divergences peuvent être exploitées pour contourner la logique de validation de domaine.
Pour plus d'informations et de paramètres sur ce contrôle de contournement : https://www.corben.io/advanced-cors-techniques/ et https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397
Depuis XSS à l'intérieur d'un sous-domaine
Les développeurs mettent souvent en place des mécanismes de défense pour se protéger contre l'exploitation de CORS en autorisant les domaines à demander des informations. Malgré ces précautions, la sécurité du système n'est pas infaillible. La présence d'un seul sous-domaine vulnérable parmi les domaines autorisés peut ouvrir la porte à l'exploitation de CORS à travers d'autres vulnérabilités, telles que XSS (Cross-Site Scripting).
Pour illustrer, considérons le scénario où un domaine, requester.com
, est autorisé à accéder aux ressources d'un autre domaine, provider.com
. La configuration côté serveur pourrait ressembler à ceci :
Dans cette configuration, tous les sous-domaines de requester.com
sont autorisés à accéder. Cependant, si un sous-domaine, par exemple sub.requester.com
, est compromis avec une vulnérabilité XSS, un attaquant peut exploiter cette faille. Par exemple, un attaquant ayant accès à sub.requester.com
pourrait exploiter la vulnérabilité XSS pour contourner les politiques CORS et accéder de manière malveillante aux ressources sur provider.com
.
Empoisonnement du cache côté serveur
Il est possible qu'en exploitant l'empoisonnement du cache côté serveur via l'injection d'en-têtes HTTP, une vulnérabilité de script intersite stockée (XSS) puisse être induite. Ce scénario se déroule lorsque une application ne nettoie pas l'en-tête Origin
des caractères illégaux, créant une vulnérabilité particulièrement pour les utilisateurs d'Internet Explorer et Edge. Ces navigateurs considèrent (0x0d) comme un terminateur d'en-tête HTTP légitime, entraînant des vulnérabilités d'injection d'en-têtes HTTP.
Considérez la requête suivante où l'en-tête Origin
est manipulé :
Internet Explorer et Edge interprètent la réponse comme suit :
Bien que l'exploitation directe de cette vulnérabilité en faisant envoyer un en-tête malformé par un navigateur web ne soit pas réalisable, une requête personnalisée peut être générée manuellement à l'aide d'outils comme Burp Suite. Cette méthode pourrait entraîner la sauvegarde de la réponse dans un cache côté serveur et sa diffusion involontaire à d'autres. La charge utile personnalisée vise à modifier l'ensemble de caractères de la page en UTF-7, un encodage de caractères souvent associé aux vulnérabilités XSS en raison de sa capacité à encoder des caractères de manière à pouvoir être exécutés comme script dans certains contextes.
Pour plus d'informations sur les vulnérabilités XSS stockées, consultez PortSwigger.
Remarque : L'exploitation des vulnérabilités d'injection d'en-tête HTTP, en particulier via l'empoisonnement du cache côté serveur, souligne l'importance critique de la validation et de la désinfection de toutes les entrées fournies par l'utilisateur, y compris les en-têtes HTTP. Employez toujours un modèle de sécurité robuste qui inclut une validation des entrées pour prévenir de telles vulnérabilités.
Empoisonnement du cache côté client
Dans ce scénario, une instance d'une page web reflétant le contenu d'un en-tête HTTP personnalisé sans codage approprié est observée. Plus précisément, la page web reflète le contenu inclus dans un en-tête X-User-id
, qui pourrait inclure du JavaScript malveillant, comme le montre l'exemple où l'en-tête contient une balise d'image SVG conçue pour exécuter du code JavaScript lors du chargement.
Les politiques de partage des ressources entre origines (CORS) permettent l'envoi d'en-têtes personnalisés. Cependant, sans que la réponse soit directement rendue par le navigateur en raison des restrictions CORS, l'utilité d'une telle injection pourrait sembler limitée. Le point critique survient lors de la prise en compte du comportement du cache du navigateur. Si l'en-tête Vary: Origin
n'est pas spécifié, il devient possible que la réponse malveillante soit mise en cache par le navigateur. Par la suite, cette réponse mise en cache pourrait être rendue directement lors de la navigation vers l'URL, contournant ainsi le besoin de rendu direct lors de la requête initiale. Ce mécanisme renforce la fiabilité de l'attaque en exploitant la mise en cache côté client.
Pour illustrer cette attaque, un exemple de JavaScript est fourni, conçu pour être exécuté dans l'environnement d'une page web, par exemple via un JSFiddle. Ce script effectue une action simple : il envoie une requête à une URL spécifiée avec un en-tête personnalisé contenant le JavaScript malveillant. Après l'achèvement réussi de la requête, il tente de naviguer vers l URL cible, déclenchant potentiellement l'exécution du script injecté si la réponse a été mise en cache sans une gestion appropriée de l'en-tête Vary: Origin
.
Voici un résumé du JavaScript utilisé pour exécuter cette attaque :
Contournement
XSSI (Inclusion de script inter-sites) / JSONP
XSSI, également connu sous le nom d'Inclusion de script inter-sites, est un type de vulnérabilité qui profite du fait que la Politique de même origine (SOP) ne s'applique pas lors de l'inclusion de ressources à l'aide de la balise script. Cela est dû au fait que les scripts doivent pouvoir être inclus à partir de différents domaines. Cette vulnérabilité permet à un attaquant d'accéder et de lire tout contenu inclus à l'aide de la balise script.
Cette vulnérabilité devient particulièrement significative lorsqu'il s'agit de JavaScript dynamique ou de JSONP (JSON avec rembourrage), surtout lorsque des informations d'autorité ambiante comme les cookies sont utilisées pour l'authentification. Lors de la demande d'une ressource à partir d'un hôte différent, les cookies sont inclus, les rendant accessibles à l'attaquant.
Pour mieux comprendre et atténuer cette vulnérabilité, vous pouvez utiliser le plugin BurpSuite disponible sur https://github.com/kapytein/jsonp. Ce plugin peut aider à identifier et à résoudre les vulnérabilités XSSI potentielles dans vos applications web.
En savoir plus sur les différents types de XSSI et comment les exploiter ici.
Essayez d'ajouter un paramètre callback
dans la requête. Peut-être que la page était préparée pour envoyer les données sous forme de JSONP. Dans ce cas, la page renverra les données avec Content-Type: application/javascript
, ce qui contournera la politique CORS.
Contournement facile (inutile ?)
Une façon de contourner la restriction Access-Control-Allow-Origin
est de demander à une application web de faire une requête en votre nom et de renvoyer la réponse. Cependant, dans ce scénario, les informations d'identification de la victime finale ne seront pas envoyées car la requête est faite à un domaine différent.
CORS-escape : Cet outil fournit un proxy qui transmet votre requête avec ses en-têtes, tout en falsifiant l'en-tête Origin pour correspondre au domaine demandé. Cela contourne efficacement la politique CORS. Voici un exemple d'utilisation avec XMLHttpRequest :
simple-cors-escape : Cet outil offre une approche alternative pour la mise en proxy des requêtes. Au lieu de transmettre votre requête telle quelle, le serveur effectue sa propre requête avec les paramètres spécifiés.
Contournement Iframe + Popup
Vous pouvez contourner les vérifications CORS telles que e.origin === window.origin
en créant un iframe et en ouvrant une nouvelle fenêtre à partir de celui-ci. Plus d'informations sur la page suivante :
Réaffectation DNS via TTL
La réaffectation DNS via TTL est une technique utilisée pour contourner certaines mesures de sécurité en manipulant les enregistrements DNS. Voici comment cela fonctionne :
L'attaquant crée une page web et fait en sorte que la victime y accède.
L'attaquant modifie ensuite le DNS (IP) de son propre domaine pour pointer vers la page web de la victime.
Le navigateur de la victime met en cache la réponse DNS, qui peut comporter une valeur TTL (Time to Live) indiquant pendant combien de temps l'enregistrement DNS doit être considéré comme valide.
Lorsque le TTL expire, le navigateur de la victime effectue une nouvelle requête DNS, permettant à l'attaquant d'exécuter du code JavaScript sur la page de la victime.
En maintenant le contrôle sur l'IP de la victime, l'attaquant peut recueillir des informations de la victime sans envoyer de cookies au serveur de la victime.
Il est important de noter que les navigateurs disposent de mécanismes de mise en cache qui peuvent empêcher l'abus immédiat de cette technique, même avec des valeurs TTL faibles.
La réaffectation DNS peut être utile pour contourner les vérifications IP explicites effectuées par la victime ou pour des scénarios où un utilisateur ou un bot reste sur la même page pendant une période prolongée, permettant à la mise en cache d'expirer.
Si vous avez besoin d'un moyen rapide d'abuser de la réaffectation DNS, vous pouvez utiliser des services comme https://lock.cmpxchg8b.com/rebinder.html.
Pour exécuter votre propre serveur de réaffectation DNS, vous pouvez utiliser des outils comme DNSrebinder (https://github.com/mogwailabs/DNSrebinder). Cela implique d'exposer votre port local 53/udp, de créer un enregistrement A pointant vers celui-ci (par exemple, ns.example.com) et de créer un enregistrement NS pointant vers le sous-domaine A précédemment créé (par exemple, ns.example.com). Tout sous-domaine du sous-domaine ns.example.com sera alors résolu par votre hôte.
Vous pouvez également explorer un serveur en cours d'exécution publiquement sur http://rebind.it/singularity.html pour une meilleure compréhension et expérimentation.
Réaffectation DNS via Inondation du cache DNS
La réaffectation DNS via l'inondation du cache DNS est une autre technique utilisée pour contourner le mécanisme de mise en cache des navigateurs et forcer une deuxième requête DNS. Voici comment cela fonctionne :
Initialement, lorsque la victime effectue une requête DNS, elle reçoit l'adresse IP de l'attaquant en réponse.
Pour contourner la défense de mise en cache, l'attaquant exploite un service worker. Le service worker inonde le cache DNS, ce qui supprime efficacement le nom de serveur de l'attaquant mis en cache.
Lorsque le navigateur de la victime effectue une deuxième requête DNS, il reçoit maintenant l'adresse IP 127.0.0.1, qui fait généralement référence à l'localhost.
En inondant le cache DNS avec le service worker, l'attaquant peut manipuler le processus de résolution DNS et forcer le navigateur de la victime à effectuer une deuxième requête, cette fois-ci se résolvant à l'adresse IP souhaitée par l'attaquant.
Réaffectation DNS via Cache
Une autre façon de contourner la défense de mise en cache est d'utiliser plusieurs adresses IP pour le même sous-domaine dans le fournisseur DNS. Voici comment cela fonctionne :
L'attaquant configure deux enregistrements A (ou un seul enregistrement A avec deux IPs) pour le même sous-domaine dans le fournisseur DNS.
Lorsqu'un navigateur vérifie ces enregistrements, il reçoit les deux adresses IP.
Si le navigateur décide d'utiliser en premier l'adresse IP de l'attaquant, l'attaquant peut servir une charge utile qui effectue des requêtes HTTP vers le même domaine.
Cependant, une fois que l'attaquant obtient l'adresse IP de la victime, il cesse de répondre au navigateur de la victime.
Le navigateur de la victime, en réalisant que le domaine est injoignable, passe à utiliser la deuxième adresse IP donnée.
En accédant à la deuxième adresse IP, le navigateur contourne la Politique de même origine (SOP), permettant à l'attaquant d'exploiter cela et de recueillir et d'extraire des informations.
Cette technique exploite le comportement des navigateurs lorsque plusieurs adresses IP sont fournies pour un domaine. En contrôlant stratégiquement les réponses et en manipulant le choix de l'adresse IP du navigateur, un attaquant peut exploiter la SOP et accéder aux informations de la victime.
Notez que pour accéder à localhost, vous devriez essayer de réaffecter 127.0.0.1 sous Windows et 0.0.0.0 sous Linux. Des fournisseurs tels que godaddy ou cloudflare ne m'ont pas permis d'utiliser l'IP 0.0.0.0, mais AWS route53 m'a permis de créer un enregistrement A avec 2 IPs, l'une d'entre elles étant "0.0.0.0"
Pour plus d'informations, vous pouvez consulter https://unit42.paloaltonetworks.com/dns-rebinding/
Autres contournements courants
Si les adresses IP internes ne sont pas autorisées, ils pourraient oublier d'interdire 0.0.0.0 (fonctionne sur Linux et Mac)
Si les adresses IP internes ne sont pas autorisées, répondez avec un CNAME vers localhost (fonctionne sur Linux et Mac)
Si les adresses IP internes ne sont pas autorisées dans les réponses DNS, vous pouvez répondre avec des CNAME vers des services internes tels que www.corporate.internal.
Arme DNS Rebidding Weaponized
Vous pouvez trouver plus d'informations sur les techniques de contournement précédentes et comment utiliser l'outil suivant dans la présentation Gerald Doussot - State of DNS Rebinding Attacks & Singularity of Origin - DEF CON 27 Conference.
Singularity of Origin
est un outil pour effectuer des attaques de rebinding DNS. Il comprend les composants nécessaires pour lier l'adresse IP du serveur d'attaque au nom DNS de la machine cible à l'adresse IP de la machine cible et pour servir des charges utiles d'attaque pour exploiter des logiciels vulnérables sur la machine cible.
Protection réelle contre le rebinding DNS
Utilisez TLS dans les services internes
Demandez une authentification pour accéder aux données
Validez l'en-tête Host
https://wicg.github.io/private-network-access/: Proposition d'envoyer toujours une requête préalable lorsque des serveurs publics veulent accéder à des serveurs internes
Outils
Fuzz les mauvaises configurations possibles dans les politiques CORS
Références
Last updated