Dans le cadre de La mission de Checkmarx Pour aider les organisations à développer et à déployer des logiciels sécurisés, l’équipe de recherche sur la sécurité a commencé à examiner la posture de sécurité des principaux constructeurs automobiles. Porsche a une politique de signalement des vulnérabilités bien établie (politique de divulgation)[1]il a été considéré comme faisant partie de la portée de nos recherches, nous avons donc décidé de commencer par là et de voir ce que nous pouvions trouver.

Ce que nous avons trouvé est un scénario d’attaque qui résulte de l’enchaînement de problèmes de sécurité trouvés sur différents actifs de Porsche, un site Web et une API GraphQL, qui pourrait conduire à une exfiltration de données. L’exfiltration de données est une technique d’attaque qui peut avoir un impact sur les entreprises et les organisations, quelle que soit leur taille. Lorsque des utilisateurs malveillants pénètrent dans les systèmes d’une entreprise ou d’une organisation et exfiltrent des données, cela peut être un moment choquant et critique pour l’entreprise.

Porsche a une présence en ligne diversifiée – déployant plusieurs microsites, sites Web et applications Web. L’expérience Porsche [2] est un site Web qui permet aux utilisateurs enregistrés de gérer un garage virtuel, de réserver des expériences (telles que des journées de piste), ainsi que de gérer les réservations et les factures. D’un point de vue technique, ce site Web est une application d’une seule page (SPA) soutenue par une API GraphQL (https://experience.porsche.com/graphql) utilisée pour récupérer des données et effectuer des opérations telles que l’authentification de l’utilisateur, les mises à jour du profil de l’utilisateur, la réservation événements, etc…

Lors de l’exploration initiale du site Web, l’équipe a remarqué des demandes d’API intéressantes. Plus précisément, le cookie jwtToken et l’en-tête de requête HTTP Appauthorization avaient tous deux la même valeur.

L’image ci-dessus montre la demande d’API d’origine émise par le frontal du site Web pour récupérer le profil de l’utilisateur après une tentative de connexion réussie. Sur la gauche (Demande), vous pouvez voir la valeur en double.

C’était suffisant pour produire une hypothétique Cross-site Request Forgery (CSRF) [3] scénario d’attaque, nous amenant à nous demander si l’API chercherait le jeton d’authentification dans le cookie jwtToken si l’en-tête de requête HTTP personnalisé Appauthorization manquait.

L’inclusion de jetons d’authentification d’API dans un en-tête de demande, plutôt que dans un cookie, change la donne pour Cross-Site Request Forgery (CSRF). Les navigateurs Web, contrairement aux cookies, n’incluent pas automatiquement ces en-têtes, ce qui doit être fait par une logique personnalisée frontale (JavaScript).

Pour répondre à notre question, nous avons relu la requête d’origine sans inclure l’en-tête de requête Appauthorization. Lorsque nous avons reçu la même réponse du serveur API, nous avons confirmé notre théorie : l’API récupère le jeton d’authentification à partir des cookies lorsque l’en-tête de requête personnalisé n’est pas présent.

Nous avions une autre question en tête à laquelle il fallait également répondre : le serveur API autoriserait-il les requêtes provenant d’autres origines que porsche.com ?

La réponse à cette question était également un « oui » retentissant.

Comme vous pouvez le voir dans l’image ci-dessus, la demande a été faite à partir d’un site Web différent, ce qui est reflété dans Access-Control-Allow-Origin [4] en-tête de réponse, indiquant que la réponse peut être partagée avec le code demandeur de l’origine donnée. De plus, le serveur d’API indique également aux navigateurs d’exposer la réponse au code JavaScript frontal lorsque le mode d’identification de la demande est inclus. [5].

En règle générale, pour pouvoir perpétrer une attaque CSRF à partir d’un site Web contrôlé par un attaquant, les navigateurs Web des victimes doivent automatiquement inclure le cookie jwtToken dans les requêtes API. Ce n’était pas le cas pour Porsche Experience : l’attribut SameSite du cookie jwtToken était défini sur Lax.

L’attribut SameSite [6] contrôle si un cookie doit être envoyé avec des requêtes intersites offrant une certaine protection contre les attaques CSRF. Lax signifie que le cookie n’est pas envoyé sur les requêtes intersites[7], et il s’agit de la valeur par défaut lorsqu’elle n’est pas spécifiée au moment où le cookie est défini. Nous ne serions pas en mesure de faire une demande à l’API GraphQL à partir d’un site Web contrôlé par nous, mais la définition de « Site » et « Same Site » [8] nous laisse encore une opportunité.

Tout site Web servi à partir d’un sous-domaine de porsche.com utilisant HTTPS est considéré comme « Same Site », et le jwtToken est automatiquement inclus par les navigateurs Web dans les requêtes adressées à l’API. Ensuite, tout ce dont nous avons besoin pour exfiltrer les données de l’API est de trouver un moyen de diriger un site Web Porsche pour émettre des requêtes API à notre API cible, en envoyant la réponse à un serveur que nous contrôlons. Il ne faut pas s’attendre à trouver une telle fonctionnalité sur un site Porsche, mais une vulnérabilité de type Cross-Site Scripting (XSS) [9] nous permettrait de le faire.

Le processus de reconnaissance initial nous a donné une liste complète des sites Web Porsche que nous avons pris en compte dans nos recherches. campagnes.porsche.com était un site Web vulnérable et le plus crédible pour être inclus dans un e-mail de phishing de « campagne marketing ».

Le point de terminaison /charge/WebAjaxGet du site Web vulnérable (campaigns.porsche.com) n’a pas correctement nettoyé ni encodé les valeurs des paramètres de la chaîne de requête avant de les inclure dans la réponse du serveur HTML. Des acteurs malveillants auraient pu exploiter ce problème pour injecter du code arbitraire dans la réponse du serveur, qui finirait par être exécuté par le navigateur Web dans le contexte de session des victimes. Vous trouverez ci-dessous l’URL spécialement conçue qui a déclenché la boîte de dialogue d’alerte dans l’image ci-dessus :

Pour exfiltrer les données de l’API vers un serveur distant, contrôlé par nous, nous avions besoin d’une logique JavaScript plus complexe. Nous avons fini par exploiter la vulnérabilité Reflected XSS pour charger un script JavaScript depuis notre serveur distant. Voici à quoi ressemble la charge utile :

L’extrait crée simplement un élément de script, définissant l’attribut src avec l’adresse à partir de laquelle notre script malveillant doit être récupéré. Lors de son ajout au Document Object Model (DOM), le script est ensuite téléchargé et exécuté. Pour éviter les problèmes d’encodage, la charge utile JavaScript a été encodée en base64 et ajoutée à l’URL en tant qu’argument de la fonction JavaScript atob, dont la sortie est transmise à la fonction eval. Voici à quoi ressemble l’URL finale conçue :

L’étape suivante consistait à écrire le script malveillant exfiltrate.js, téléchargé et exécuté par notre payload XSS. Pour les victimes, ayant une session active sur experience.porsche.com, le cookie d’authentification jwtToken est automatiquement inclus dans les requêtes à l’API. Tout ce dont nous avons besoin est de déclencher la requête avec la requête GraphQL appropriée et d’envoyer la réponse à notre serveur distant. Pour rendre l’attaque un peu plus robuste, nous redirigerons ensuite le navigateur vers le site Web Porsche Experience.

Avec tout en place et fonctionnant correctement, les acteurs malveillants devraient fournir l’URL malveillante finale aux victimes, les incitant à cliquer dessus. Le phishing par e-mail est certainement la méthode la plus courante utilisée par les attaquants. L’image ci-dessous illustre un tel e-mail de phishing : au lieu d’essayer de masquer l’URL, l’attaquant peut avoir profité du fait qu’il commence par HTTPS, et qu’il s’agit d’un véritable site Web porsche.com.

Ce scénario d’attaque n’est pas théorique, et vous pouvez regarder la vidéo de preuve de concept fournie à Porsche sur YouTube [10].

Bien que cette preuve de concept se concentre sur l’exfiltration des données de profil, le script JavaScript chargé pourrait inclure une autre logique pour récupérer des données supplémentaires à partir de l’API GraphQL (par exemple, des factures) ou effectuer des actions au nom des victimes (par exemple, réserver ou annuler des événements).

Quelques conseils de sécurité rapides :

Pour empêcher XSS [11] toujours encoder les données non sécurisées, selon le contexte dans lequel elles seront écrites. Du côté des API, établissez toujours une politique appropriée de partage des ressources cross-origin (CORS) [12] qui limite les hôtes autorisés à interagir avec lui. Définissez également correctement les options des cookies et, dans la mesure du possible, évitez d’utiliser des cookies pour échanger des jetons d’authentification entre les clients et le serveur API.

Ce fut un plaisir de collaborer avec Porsche qui s’est approprié et a été professionnel tout au long du processus de divulgation et de remédiation. Pour cette raison, et une excellente expérience de recherche, nous accordons à Porsche le sceau d’approbation Checkmarx.

Et, comme toujours, notre équipe de recherche en sécurité continuera de se concentrer sur les moyens de améliorer les pratiques de sécurité des applications partout.

A lire également