Universal Cross Site Scripting

L’objectif de cet article est de découvrir un type de vulnérabilité atypique concernant les navigateurs : les XSS universelles. Pour cela, dans un premier temps, un rappel détaillé des protections existantes au sein des navigateurs (la Same Origin Policy (SOP), les entêtes CORS et jetons) sera réalisé.

Ensuite, l’article décrira comment les vulnérabilités de type Cross Site Scripting (XSS) et Cross Site Scripting universelles (UXSS) permettent de contourner toutes ces sécurités. Pour finir, des exemples d’UXSS seront présentés afin d’imager le fonctionnement de ce type de vulnérabilités.

Introduction

Depuis la création du premier navigateur web nommé World Wide Web en 1990, les navigateurs n’ont cessé d’évoluer au même rythme qu’Internet se démocratisait pour le plus grand nombre. En rendant accessible rapidement et simplement les ressources exposées sur Internet, les navigateurs se sont très vite imposés comme un élément central au sein de l’écosystème Internet et font désormais partie intégrante de la vie de plus de cinq milliards d’utilisateurs.

En 30 ans d’évolution, les navigateurs web sont devenus des logiciels très complexes qui rendent désormais possible l’existence de sites dynamiques au design travaillé. Tout cela est possible grâce aux nombreux composants d’un navigateur qui permettent notamment l’interprétation des feuilles de style en cascade, l’utilisation du langage JavaScript ou encore le stockage de cookies.

Cette évolution des navigateurs a permis la création de sites complexes permettant de réaliser tout type de tâches comme l’envoi de mail, le partage de données ou encore l’accès à un compte bancaire. Il est possible de contrôler tous les aspects de sa vie depuis un navigateur web.

Les XSS universelles

Au vu de l’importance des navigateurs web, des données qu’ils manipulent et des nombreuses tâches qu’ils permettent d’accomplir, leur sécurité est un aspect primordial. Les différentes ressources interprétées et affichées par les navigateurs n’étant pas issues de sources sûres, il est primordial que leur traitement ne présente aucune faille de sécurité étant donné l’impact que cela pourrait avoir sur l’utilisateur.

« L’objectif de cet article est de rappeler le fonctionnement d’un navigateur et les sécurités existantes avant de présenter en détail un type de faille affectant les fonctionnalités d’un navigateur : les vulnérabilités de type « Cross-Site Scripting » universelles (UXSS). »

Les failles de sécurité au sein d’un navigateur sont très souvent critiques, car elles sont facilement exploitables à l’aide d’un site web malveillant et peuvent mener au vol de données très sensibles.

Une particularité de la sécurité des navigateurs web vient du fait que la responsabilité pour la sécurité est partagée :

  • Une première partie de la responsabilité repose sur le créateur du site web qui doit s’assurer que son site ne présente aucune vulnérabilité côté client qui pourrait mener à des attaques entre différents utilisateurs du même site web ;
  • Une autre part de la responsabilité est du côté du serveur hébergeant le site web. Il est important qu’il soit à jour et ne présente aucune faille qui pourrait avoir des répercussions sur le site et ses utilisateurs ;
  • Enfin, une partie importante de la responsabilité est du côté du navigateur qui doit s’assurer qu’un site malveillant ne peut pas compromettre les informations d’un autre site respectant toutes les bonnes pratiques de sécurité.

L’objectif de cet article est de rappeler le fonctionnement d’un navigateur et les sécurités existantes avant de présenter en détail un type de faille affectant les fonctionnalités d’un navigateur : les vulnérabilités de type Cross-Site Scripting universelles (UXSS) Le but est de montrer comment une telle faille peut permettre de contourner les sécurités existantes et rend possible la réalisation d’attaques sur des sites parfaitement sécurisés.

Fonctionnement d’un navigateur web

Avant de détailler le fonctionnement des XSS universelles, il est important de comprendre le fonctionnement d’un navigateur.

Comme cela a été évoqué dans l’introduction, les navigateurs sont désormais très complexes et constitués de divers éléments connectés les uns aux autres. Le schéma ci-dessous représente les principaux composants utilisés par le navigateur lors du chargement d’un site web :

Schéma résumant le fonctionnement d’un navigateur
Schéma résumant le fonctionnement d’un navigateur

Une fois que l’utilisateur a renseigné, à l’aide de cette interface, l’URL du site web qu’il souhaite consulter, le navigateur va alors transmettre l’information au composant réseau du navigateur qui va se charger de récupérer les sources du site cible en requêtant un serveur distant.
Une fois tous les fichiers récupérés, ils vont être fournis à deux composants majeurs du navigateur :

  • Le moteur de rendu : Ce composant a pour rôle d’interpréter le code HTML et CSS reçu et de générer une représentation de la page correspondante au sein du navigateur. On appelle cette représentation le DOM (Document Object Model). Cette représentation facilite ensuite la manipulation de la page depuis le JavaScript mais sert aussi de base pour le rendu graphique qui permet d’afficher correctement le contenu à l’utilisateur.
  • Le moteur JavaScript : Ce composant est chargé d’interpréter le code JavaScript et de l’exécuter. Ce dernier est appelé après la création du DOM car il peut interagir avec et le modifier.

Enfin, la plupart des sites web utilisent le composant de stockage du navigateur afin de stocker les cookies de session ou toutes autres données nécessaires pour le fonctionnement du site. Les différents sites peuvent accéder à ce stockage par le biais d’instructions JavaScript.

Protections existantes

Les mécanismes

Le schéma présenté dans la partie précédente résume le fonctionnement d’un navigateur lors de l’accès à un unique site internet. En réalité, les navigateurs sont amenés à charger plusieurs sites en simultané, que ce soit par le biais d’onglets ou avec l’utilisation d’iframes qui permettent d’inclure un site web au sein d’un autre.

Et c’est lors de l’accès à plusieurs sites en simultané que la sécurité du navigateur est importante. En effet, c’est le rôle du navigateur d’assurer que les différents sites ne peuvent interagir entre eux que lorsque cela est strictement nécessaire et légitime.
Le code JavaScript hébergé sur le site d’un attaquant ne doit pas pouvoir interagir librement avec les fonctionnalités et informations du site bancaire ouvert dans un autre onglet.
Pour cela, des mécanismes de sécurité ont été définis et s’appliquent au sein de tous les navigateurs web :

  • La politique Same Origin Policy (SOP)
  • Les entêtes Cross Origin Resource Sharing (CORS)

Same Origin Policy (SOP)

La Same Origin Policy (SOP) est un mécanisme de sécurité implémenté au niveau applicatif par tous les navigateurs modernes.
Avant d’expliquer le fonctionnement de cette politique, il est nécessaire de comprendre comment est définie l’origine d’un site web. Dans le cadre de la SOP, l’origine d’une page est définie par le tuple protocole / hôte / port qui peut être extrait de l’URL.

Description des attributs constituant une origine
Description des attributs constituant une origine

En se basant sur ces informations, la SOP permet de restreindre les interactions entre les différents sites web ouverts au sein d’un navigateur en définissant les règles suivantes :

  • Les sites ouverts par un navigateur disposent chacun d’un espace dédié dans lequel sont contenues les informations qui lui sont propres comme les cookies et le DOM ;
  • L’espace dans lequel est isolé un site dépend de son origine (schéma + domaine + port) ;
  • Le code JavaScript d’un site ne peut interagir qu’avec les ressources présentes dans l’espace dédié au site depuis lequel il s’exécute.

Ces règles permettent donc d’assurer qu’un script chargé depuis une origine ne peut pas interagir avec une ressource d’une autre origine. Cela permet donc d’empêcher un site hébergeant du code JavaScript malveillant de dérober les informations d’un autre site ouvert par le navigateur car ce dernier sera isolé dans son propre espace.

Voici un résumé des communications possibles entre différentes pages web lorsque la Same Origin Policy s’applique :

Résumé des communications possibles entre différentes pages web lorsque la Same Origin
Policy s’applique

Par exemple, dans le cas d’un utilisateur avec deux onglets ouverts dans son navigateur, imaginons que l’utilisateur utilise le premier onglet pour se connecter à sa boite mail (emails.test.com) et que dans le second onglet, il se soit fait piéger et ait ouvert le site d’un attaquant (attacker.test.com).

Exemple d’erreur générée lors de l’accès aux attributs d’une iframe depuis une autre origine
Exemple d’erreur générée lors de l’accès aux attributs d’une iframe depuis une autre origine

En se connectant à sa webmail, l’utilisateur s’est vu attribuer un cookie authentifiant que le navigateur a stocké. Un scénario d’exploitation pour récupérer ce cookie depuis le site de l’attaquant pourrait donc
être le suivant :

  1. Le site de l’attaquant inclut une copie du site de mails à l’aide d’une iframe ;
  2. Le site de l’attaquant tente d’accéder aux cookies du site de mails par le biais du DOM de l’iframe.

La réalisation d’un tel scénario serait possible au sein d’un navigateur n’appliquant pas la SOP.
Heureusement, pour tout navigateur appliquant cette politique, l’instruction JavaScript visant à accéder au DOM de l’iframe sera bloquée car l’origine depuis laquelle s’exécute le code est différente de celle de l’iframe.

Par exemple, en essayant de réaliser une telle opération depuis un navigateur Mozilla Firefox, le code JavaScript est bien bloqué par la SOP (voir capture ci-dessous). L’iframe s’affiche pour l’utilisateur, mais il est impossible pour le code JavaScript du site de l’attaquant d’accéder à ce que l’utilisateur voit au sein de l’iframe. Mais la SOP ne s’applique pas uniquement au DOM. Cette politique permet aussi de protéger les accès réseau entre deux documents d’origines différentes.
En reprenant le cas précédent, le navigateur a stocké les cookies du site et les transmet, avec chaque requête, à destination de ce dernier. Cela signifie donc que les requêtes émises depuis un site malveillant vers le site de mails incluront aussi le cookie d’authentification de l’utilisateur.

Un nouveau scénario d’attaque pourrait donc consister à émettre une requête vers une route permettant de lister les mails de l’utilisateur depuis un site malveillant afin de voler tous les mails de la victime.
Cependant, dans le cadre de requêtes GET simples, les navigateurs appliquant la SOP bloquent la lecture des réponses aux requêtes inter-origines. Ainsi, un site malveillant peut émettre des requêtes GET vers un site d’une autre origine mais il n’aura pas accès à la réponse depuis le code JavaScript.

Schéma du fonctionnement de la SOP dans le cas d’une requête GET simple
Schéma du fonctionnement de la SOP dans le cas d’une requête GET simple

Ce document est la propriété du cabinet XMCO. Toute reproduction est strictement interdite. En testant un tel scénario sur un navigateur Mozilla Firefox, il est possible d’observer que la SOP est bien appliquée. La requête est transmise vers le site de mails mais la lecture de la réponse depuis le code JavaScript est bloquée par le navigateur :

Exemple d’erreur générée lors de l’émission d’une requête GET simple inter-origines
Exemple d’erreur générée lors de l’émission d’une requête GET simple inter-origines

« La SOP permet donc bien de protéger l’utilisateur en empêchant un site malveillant d’accéder aux informations d’autres sites, que ce soit en passant par le DOM ou en passant par le biais de requêtes inter-origines. »

Cependant, la protection de la SOP dans le second cas est complexe et peut varier en fonction de la méthode utilisée par la requête.
Dans la prochaine partie, l’objectif est donc de revenir plus en détail sur la protection assurée par la SOP lors de l’émission de requêtes inter-origines.

Cross Origin Request Sharing (CORS)

Dans la partie précédente, l’exemple utilisé pour décrire la protection mise en place par la SOP dans le cadre de requêtes inter-origines concernait une requête GET simple et démontrait que le navigateur permettait l’émission de la requête mais pas la lecture de la réponse par le code JavaScript. Ce comportement peut varier et dépend du type de requête émise. Voici les deux types de requêtes pour lesquelles les vérifications réalisées par le navigateur vont varier :

Universal Cross Site Scripting #2

Requêtes « simples »

Dans le cadre de requêtes « simples », la protection du navigateur est celle observée dans la partie précédente.
Par défaut, entre deux origines différentes, la requête est bien émise mais la réponse n’est pas accessible par le code JavaScript du site émetteur. Cette protection empêche donc un site malveillant d’accéder au contenu d’un autre site, mais pas de réaliser des actions sur ce site par le biais de requêtes POST.

Par exemple, en utilisant encore une fois le cas d’un utilisateur connecté à sa boîte mail en ligne et qui se rend sur le site d’un attaquant : si le site de l’attaquant émet une requête inter-origine pour envoyer un mail, alors le mail sera envoyé avec succès depuis le compte de la victime, même si la réponse n’est pas récupérable depuis le site de l’attaquant :

Schéma du fonctionnement de la SOP dans le cas d’une requête POST simple

Tout comme les exemples précédents, ce comportement est observable sur Mozilla Firefox.
Ici la requête POST émise par le site malveillant a bien utilisé les cookies de l’utilisateur afin d’envoyer un mail en son nom, mais il reste impossible de lire la réponse obtenue :

Exemple d’erreur générée lors de l’émission d’une requête POST simple inter-origines
Exemple d’erreur générée lors de l’émission d’une requête POST simple inter-origines

NOTE : L’envoi de requêtes « simples » inter-origines usurpant l’identité d’un utilisateur est une faiblesse connue de la SOP. Ce type d’attaque est connue sous le nom de Cross Site Request Forgery (CSRF). Les protections existantes pour se protéger de ces attaques seront détaillées dans la suite de l’article.

Requêtes « preflight »

Pour le second type de requêtes, les requêtes « preflight », la protection est différente et la requête ne sera émise que si le site cible l’accepte. Les CSRF ne sont donc pas possibles avec ce type de requêtes. Afin que cela soit possible, une première requête OPTIONS est émise par le navigateur vers le site cible. Cette requête contient toutes les informations de la requête émise initialement. Le site web cible va alors répondre à cette requête avec la liste des options pour lesquelles il accepte des requêtes issues d’autres origines. Le navigateur va ensuite comparer les options de la requête initiale à celles attendues par le serveur distant et choisir d’autoriser ou non l’envoi de cette requête.

Par défaut, les serveurs ne sont pas configurés pour accepter les requêtes inter-origines. Le fonctionnement est donc le suivant et l’envoi des requêtes inter-origines est refusé :

Schéma du fonctionnement de la SOP dans le cas de requêtes « preflight » émises vers une application n’utilisant pas d’entêtes
CORS
Schéma du fonctionnement de la SOP dans le cas de requêtes « preflight » émises vers une application n’utilisant pas d’entêtes CORS

« Pour le second type de requêtes, les requêtes « preflight », la protection est différente et la requête ne sera émise que si le site cible l’accepte. Les CSRF ne sont donc pas possibles avec ce type de requêtes. »

Ce comportement peut, encore une fois, être observé depuis un navigateur :

Exemple d’erreurs générées lors de l’émission d’une requête « preflight » émise vers une application n’utilisant pas d’entêtes CORS

Ici une requête OPTIONS est bien envoyée avant la requête initiale. La réponse à cette requête n’autorisant pas explicitement l’émission de la requête initiale, une erreur est générée et la requête DELETE n’est jamais envoyée vers le site de mails.

Configuration des CORS

Pour les deux types de requêtes présentées dans la partie précédente, le navigateur applique donc la SOP afin de limiter au maximum l’émission de requêtes malveillantes. Mais dans certains cas, les requêtes inter-origines sont légitimes. Il est donc possible, quel que soit le type de requête, d’autoriser la communication entre deux sites d’origines différentes.

Pour cela, il est possible de configurer l’envoi d’entêtes CORS par le serveur hébergeant l’application souhaitant autoriser les requêtes issues d’autres origines :

  • Access-Control-Allow-Origin : cet entête contient une liste des origines autorisées à requêter le serveur
  • Access-Control-Allow-Methods : cet entête contient une liste des méthodes autorisées dans le cadre de requêtes inter-origines
  • Access-Control-Allow-Headers : cet entête contient une liste des entêtes autorisées dans le cadre de requêtes inter-origines
  • Access-Control-Allow-Credentials : cet entête permet d’autoriser les requêtes inter-origines authentifiées à l’aide d’un cookie

Un navigateur qui observe ces différents entêtes dans la réponse d’un serveur pourra donc autoriser les communications entre deux origines si la requête respecte les différents entêtes CORS. L’utilisation de ces entêtes est valable dans le cas de requêtes preflight :

Schéma du fonctionnement de la SOP dans le cas de requêtes « preflight » émises vers une application configurée pour utiliser des entêtes CORS
Schéma du fonctionnement de la SOP dans le cas de requêtes « preflight » émises vers une application configurée pour utiliser des entêtes CORS

Dans le cas de requêtes « simples », les entêtes CORS permettent au code JavaScript de lire la réponse fournie par le serveur distant :

Schéma du fonctionnement de la SOP dans le cas de requêtes « simples » émises vers une application configurée pour utiliser
des entêtes CORS
Schéma du fonctionnement de la SOP dans le cas de requêtes « simples » émises vers une application configurée pour utiliser des entêtes CORS

Dans une telle configuration, un attaquant pourrait donc voler les mails de tous les utilisateurs se rendant sur son site tout en étant authentifié sur le site de mail dans un autre onglet. Il est donc très important de configurer prudemment les sites autorisés au sein des entêtes CORS.

NOTE : Une vulnérabilité dans un site autorisé à émettre des requêtes inter-origines vers un deuxième site est équivalente à une faille au sein des deux sites. Aussi l’utilisation de wildcard au sein des entêtes CORS (ex. : Access-Control-Allow-Origin : *) est dangereuse car elle annule les protections mises en place par la SOP et rend donc un site vulnérable.

Pour résumer, la SOP et les entêtes CORS permettent de règlementer les échanges inter-origines de manière à empêcher un site malveillant d’émettre des requêtes arbitraires vers d’autres origines. Mais comme nous l’avons observé, cette protection est imparfaite et il reste possible, dans le cas de requêtes « simples », de réaliser des actions au nom de la victime depuis un site malveillant.
Ces attaques sont connues sous le nom de Cross Site Request Forgery (CSRF) et nous allons voir dans la partie suivante comment la majorité des sites internet s’en protège.

CSRF

La protection contre les CSRF n’est pas de la responsabilité du navigateur.

C’est à cause d’une faiblesse de la SOP pour les requêtes « simples » que les CSRF sont possibles. C’est donc aux sites web de se protéger contre ce type d’attaque en mettant en place des mécanismes anti-CSRF.

Ces mécanismes sont présents sur une grande partie des sites web de nos jours et permettent de combler le manque de protection de la SOP dans le cas des requêtes « simples ».

Reprenons l’exemple du site de mail, afin d’envoyer un mail à partir de ce dernier, l’utilisateur doit remplir un formulaire puis le soumettre au serveur. Afin de soumettre le contenu de ce formulaire, c’est une requête POST qui est émise par le navigateur vers le serveur. Le serveur, une fois la requête POST reçue se charge d’envoyer le mail à partir des informations contenues dans ce formulaire.

Dans le cas où la requête POST émise lors de l’envoi d’un mail prend la forme d’une requête « simple », alors cela signifie qu’un site malveillant peut usurper l’identité d’un utilisateur, si ce dernier est connecté au site de mails dans un autre onglet, en envoyant cette requête à sa place.

Afin de remédier à cela, il est nécessaire pour le site de mails de mettre en place des jetons anti-CSRF au sein de ses formulaires. L’objectif de ces jetons est d’ajouter une part d’aléatoire aux requêtes POST émises afin d’envoyer un mail. En ajoutant une part d’aléatoire à ces requêtes, il devient impossible pour un site malveillant de recréer une requête et d’envoyer des mails à la place d’autres utilisateurs.

La mise en place d’une telle protection nécessite donc la réalisation des étapes suivantes :

  • Génération de jetons anti-CSRF aléatoires par le serveur applicatif ;
  • Transmission des jetons anti-CSRF aux clients lorsqu’ils naviguent sur le site web ;
  • Transmission des jetons anti-CSRF au sein des différentes requêtes émises par les clients ;
  • Vérification de la validité des jetons anti-CSRF par le serveur lors du traitement des requêtes.

Ce mécanisme permet d’assurer que les requêtes émises par le client sont légitimes et qu’il navigue réellement sur le site web, seul endroit où il est possible de récupérer un jeton anti-CSRF valide.

Le seul moyen pour un attaquant de contourner cette sécurité serait de réussir à récupérer un jeton anti-CSRF valide avant d’envoyer sa requête. Mais la SOP bloque la récupération du contenu des pages depuis une autre origine ce qui rend donc cette opération impossible.

« Dans une telle configuration, un attaquant pourrait donc voler les mails de tous les utilisateurs se rendant sur son site tout en étant authentifié sur le site de mail dans un autre onglet. Il est donc très important de configurer prudemment les sites autorisés au sein des entêtes CORS. »

Par exemple, dans le cas du site de mails, l’utilisation de jetons anti-CSRF permet d’empêcher l’envoi de mails depuis un site malveillant à l’aide de requêtes « simples » :

Schéma du fonctionnement d’une application utilisant des jetons CSRF
Schéma du fonctionnement d’une application utilisant des jetons CSRF

La mise en place de jetons anti-CSRF permet donc de renforcer les protections déjà mises en place par la SOP. Ensemble, ces deux mécanismes permettent de protéger un site web des attaques issues de sites web malveillants en assurant que les interactions inter-origines sont limitées.

Comment contourner ces protections

Maintenant que le fonctionnement de la SOP, des entêtes CORS et des jetons anti-CSRF ont été détaillés, l’objectif est de présenter des vulnérabilités permettant de contourner ces différentes protections.

XSS classique

Les vulnérabilités côté clients les plus fréquentes sont les failles de type Cross Site Scripting (XSS). Ces vulnérabilités sont issues d’un défaut au sein d’une application web et permettent de contourner toutes les protections présentées précédemment, dans le contexte de l’application vulnérable.

Les XSS sont courantes, car il est très fréquent pour un site web de réfléchir des valeurs contrôlables par un utilisateur au sein de ses pages. Par exemple, la plupart des sites affichent le nom de l’utilisateur avec lequel vous êtes connecté.


C’est dans ce type de cas que les failles de type XSS apparaissent. En effet, certains sites ne vérifient pas correctement les valeurs fournies par les utilisateurs avant de les injecter au sein de leurs pages. Ainsi, un utilisateur qui fournit du code JavaScript dans une entrée n’étant pas correctement filtrée peut en profiter pour injecter des instructions JavaScript au sein des pages dans lesquelles cette entrée est insérée.

Schéma du fonctionnement d’une faille de type XSS
Schéma du fonctionnement d’une faille de type XSS

Dans le cadre d’une XSS, le code JavaScript injecté s’exécutera depuis l’origine du site vulnérable. En effet, ce code se trouvera au sein de la page vulnérable du site victime et donc le navigateur l’isolera avec le reste du site. Ainsi, ce code ne sera pas bloqué par la SOP et aura accès au DOM du site tout comme il pourra requêter l’ensemble des ressources hébergées sur le site.

L’origine du code malveillant étant la même que celle du site cible, toutes les protections sont inefficaces.

Les protections mises en place par les navigateurs et l’utilisation de jetons anti-CSRF ne sont donc pas suffisantes pour assurer la sécurité d’un site web. Il est aussi nécessaire d’assurer que ce dernier ne présente aucune vulnérabilité applicative et traite correctement les entrées contrôlables par les utilisateurs.

UXSS

Les XSS nécessitent donc une vulnérabilité au sein de l’application web. La vulnérabilité qui va être présentée dans cette partie n’a pas les mêmes prérequis.

En effet, les XSS universelles (UXSS) ne sont pas propres à un site, mais permettent d’injecter du code JavaScript au sein de n’importe quel site. La réalisation d’une telle action est possible, car ce type de vulnérabilité est issu du navigateur.

Ce type de vulnérabilité est très proche des XSS classiques. L’objectif est d’injecter du code JavaScript.

Exemple d’une UXSS sur le navigateur Google Chrome

Ainsi, un attaquant qui trouve une telle vulnérabilité pourra héberger du code JavaScript malveillant permettant de réaliser tout type d’actions sur les sites de son choix : sites bancaires, webmails, réseaux sociaux…

L’attaquant n’aura plus qu’à convaincre ses victimes de se rendre sur son site. Et lorsqu’elles navigueront sur le site, si jamais elles sont authentifiées sur les sites ciblés par l’attaquant, alors le code JavaScript malveillant pourra réaliser des actions en leur nom sur ces sites.

« Les XSS universelles (UXSS) ne sont pas propres à un site mais permettent d’injecter du code JavaScript au sein de n’importe quel site. »

Exemples

Nous allons désormais présenter deux exemples d’UXSS découvertes dans les dernières années. La présentation de ces failles va permettre de souligner que les vulnérabilités de ce type peuvent être issues d’erreurs de logique au sein du navigateur, mais aussi des extensions ajoutées au navigateur.

UXSS via une vulnérabilité au sein d’un navigateur (Chrome : CVE-2017-5124)

La vulnérabilité CVE-2017-5124 touche le navigateur Google Chrome et rend possible la réalisation de
UXSS en exploitant un défaut de logique lors du traitement des documents MHTML.

Les documents MHTML (MIME Encapsulation of Aggregate HTML) permettent d’encapsuler une page web et l’ensemble de ses ressources au sein d’un fichier unique.


Un tel document est donc divisé en plusieurs parties :

  • Une première partie du document est dédiée au contenu de la page principale ;
  • Les autres parties contiennent les différentes ressources référencées par la page principale.


Pour faire le lien entre ces différentes parties, chaque partie contenant une ressource utilise un attribut Content-Location qui peut ensuite être utilisé pour y faire référence depuis la page principale.
Voici un exemple de document MHTML :

Exemple de document MHTML
Exemple de document MHTML

Un tel format de document permet donc de contrôler l’origine d’un document ainsi que son contenu. Toutes les conditions sont donc réunies pour contourner la SOP et obtenir une UXSS. Heureusement, par défaut l’exécution de code JavaScript est bloquée par le navigateur pour ce type de documents. Mais un contournement de cette protection était possible dans les versions antérieures à 62.0.3202.62 de Google Chrome.

En effet, lorsque la page principale du document MTHML est au format XSLT, alors il devient possible d’exécuter du code JavaScript au sein de cette dernière mais aussi au sein des différentes ressources auxquelles elle fait référence.

Ainsi, il est possible de créer un document MHTML au format suivant afin d’exécuter du code JavaScript sur des origines arbitraires :

Exemple de document MHTML permettant d’exploiter la faille CVE-2017-5124
Exemple de document MHTML permettant d’exploiter la faille CVE-2017-5124

En jouant sur l’attribut Content-Location et sur la source de l’iframe, il devient donc possible de contrer avec quelle origine s’exécute le code JavaScript défini dans la deuxième partie du document. C’est une UXSS. Un attaquant peut donc, par exemple, exploiter cette vulnérabilité afin de contourner la SOP et dérober le cookie d’authentification du site de mails sur lequel la victime est connectée dans un second onglet (voir capture suivante).

De la même manière que l’attaquant peut exploiter cette vulnérabilité pour accéder aux cookies de sites web, il est possible d’exploiter cette vulnérabilité pour récupérer tous les mails de l’utilisateur, envoyer des mails en son nom et supprimer des mails (même si des jetons CSRF sont utilisés).

Le code JavaScript s’exécutant dans le contexte du site de mails, ce dernier apparait comme légitime et n’a donc aucune restriction.

« Un attaquant peut donc, par exemple, exploiter cette vulnérabilité afin de contourner la SOP et de dérober le cookie d’authentification du site de mails sur lequel la victime est connectée dans un second onglet. »

Cette vulnérabilité est donc critique, car un utilisateur peut se faire compromettre simplement en naviguant sur un site malveillant depuis un navigateur n’étant pas à jour.

Exploitation de la faille CVE-2017-5124 afin de voler les cookies d’une autre origine depuis le site d’un l- ’attaquant
Exploitation de la faille CVE-2017-5124 afin de voler les cookies d’une autre origine depuis le site d’un l’attaquant

UXSS via une vulnérabilité au sein d’une extension (Evernote Web Clipper : CVE-2019-12592)

La vulnérabilité CVE-2019-12592 est la preuve du danger que peuvent représenter les extensions installées sur un navigateur. En effet, pour cette vulnérabilité, c’est l’extensionEvernote Web Clipper qui rend possible la réalisation de UXSS.

Les extensions sont utilisées pour augmenter les capacités d’un navigateur. Installer une extension sur son navigateur augmente donc sa surface d’attaque. Des vulnérabilités de type UXSS peuvent donc être introduites par le biais d’extensions.

L’extension Evernote Web Clipper peut être installée sur tous les navigateurs, dont Google Chrome, et permet aux utilisateurs de sauvegarder des articles, pages web et captures d’écrans directement dans leur application Evernote. Cette extension est un intermédiaire entre le navigateur et l’application Evernote.

Voici un aperçu de l’extension lancée au sein d’un navigateur :

Interface de l’extension Evernote Web Clipper
Interface de l’extension Evernote Web Clipper

Comme la plupart des extensions, Evernote Web Clipper injecte du code JavaScript dans toutes les pages consultées par l’utilisateur. Cela permet, par exemple, d’ajouter une interface supplémentaire sur la page ou de modifier la mise en forme de cette dernière.

En injectant du code dans toutes les pages visitées, les extensions disposent des privilèges nécessaires à la réalisation d’attaques similaires aux UXSS. Il est donc important d’installer uniquement des extensions de confiance.

La vulnérabilité provient ici du fait qu’un site malveillant peut contrôler le code JavaScript injecté par l’extension. En effet, la méthode utilisée par l’extension pour charger des scripts au sein des pages consultées par l’utilisateur n’est pas correctement sécurisée. Il est donc possible, à l’aide d’une instruction postMessage, de fournir des scripts arbitraires à l’extension pour qu’elle les injecte ensuite.

Un attaquant peut donc créer une page spécifiquement conçue contenant des instructions JavaScript permettant de modifier le code injecté par l’extension. Une fois chargé, l’extension va charger le code malveillant sur la page actuelle, mais aussi sur toutes les iframes présentes sur la page.

L’attaquant peut donc ajouter des iframes des sites qu’il cible au sein de sa page malveillante afin que le code JavaScript soit injecté, par l’extension, au sein de ces dernières.

Exemple de page HTML permettant d’exploiter la faille CVE-2019-12592
Exemple de page HTML permettant d’exploiter la faille CVE-2019-12592

L’attaquant contrôle donc le code JavaScript que l’extension injecte, mais aussi les pages sur lesquelles ce code est injecté. C’est une UXSS.

Schéma du fonctionnement de la faille CVE-2019-12592
Schéma du fonctionnement de la faille CVE-2019-12592
Exploitation de la faille CVE-2017-5124 afin d’exécuter du code JavaScript sur les sites
Exploitation de la faille CVE-2017-5124 afin d’exécuter du code JavaScript sur les sites www.youtube.com et www.google.com

Conclusion

Pour conclure, des protections robustes existent et sont appliquées par les navigateurs et les sites web afin d’assurer la sécurité des utilisateurs d’Internet.

La Same Origin Policy, les entêtes Cross-Origin Resource Sharing et les jetons anti Cross-Site Request Forgery protègent les utilisateurs en empêchant les sites malveillants d’utiliser les informations stockées par le navigateur à leurs avantages.
Cependant, aucun système n’est infaillible et des vulnérabilités comme les UXSS permettent de contourner toutes les protections existantes. Un attaquant peut exploiter de telles failles afin de voler les sessions d’un utilisateur ou encore pour réaliser des actions en son nom sur les sites qu’il a visités avec son navigateur.
Il est donc important de prendre les précautions suivantes afin de se protéger :

  • Tenir à jour son navigateur web ;
  • Cliquer uniquement sur des liens de confiance ;
  • Penser à se déconnecter d’un site une fois la navigation terminée ;
  • Installer uniquement des extensions de confiance.

Références

UXSS

[1] https://research.google/pubs/pub48028/
[2] https://www.acunetix.com/blog/articles/universal-cross-site-scripting-uxss/
[3] https://github.com/Metnew/uxss-db
[4] https://bo0om.ru/chrome-and-safari-uxss
[5] https://fr.wikipedia.org/wiki/MIME_Encapsulation_of_Aggregate_Documents,_such_as_
HTML

[6] https://www.ryanpickren.com/safari-uxss
[7] https://guard.io/blog/evernote-universal-xss-vulnerability
[8] https://www.crx4chrome.com/history/922/
[9] https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.ht-
ml?prefix=Linux_x64/488525/

SOP / CORS / CSRF

[10] https://www.invicti.com/whitepaper-same-origin-policy/
[11] https://medium.com/@zhaojunemail/sop-cors-csrf-and-xss-simply-explained-with-exa-
mples- af6119156726

[12] https://blog.vnaik.com/posts/web-attacks.html
[13] https://stackoverflow.com/questions/24680302/csrf-protection-with-cors-origin-header-vs-
csrf-token

[14] https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#cross-origin_
network_access

[15] https://www.moesif.com/blog/technical/cors/Authoritative-Guide-to-CORS-Cross-Origin-
Resource-Sharing-for-REST-APIs/

[16] https://www.acunetix.com/blog/web-security-zone/what-is-same-origin-policy/

Lucas Pech

Découvrir d'autres articles

  • Pentest

    Des dés aux données : de l’importance des nombres aléatoires (partie 2/2)

    Lire l'article
  • Pentest

    Des dés aux données : de l’importance des nombres aléatoires (partie 1/2)

    Lire l'article
  • Pentest

    Tour d’horizon des attaques et vulnérabilités sur le gestionnaire de mots de passe KeePass 

    Lire l'article