Exploitation d'Entra OAuth pour accéder aux applications internes Microsoft
(research.eye.security)- Les chercheurs ont confirmé qu'en exploitant le processus de consentement et de délégation des droits d'Entra OAuth, il était possible d'accéder aux applications internes de Microsoft
- Cette vulnérabilité constitue une nouvelle menace pour la protection des systèmes internes, puisqu'elle ouvre la possibilité qu'un utilisateur externe obtienne un accès aux services internes
- Les mécanismes de consentement de base et la mauvaise configuration des permissions sont les causes principales
- Les résultats de la recherche montrent qu'avec les contrôles de sécurité existants, une faille subsiste au niveau de la demande de consentement OAuth et du contrôle d'accès
- Les entreprises et organisations ont confirmé la nécessité de renforcer la gestion du consentement et des autorisations OAuth
Contexte et aperçu de la recherche
- Microsoft Entra OAuth est un cadre d'authentification et d'autorisation où plusieurs applications obtiennent des droits d'accès à différents services avec le consentement de l'utilisateur
- Les chercheurs ont constaté que, dans un environnement cible, des applications Microsoft normalement accessibles uniquement en interne pouvaient être atteintes depuis l'extérieur lorsqu'un scénario spécifique de consentement et de délégation d'autorisation était exploité
Analyse des causes
- La vulnérabilité survient par l'exploitation du processus de demande de consentement OAuth
- Si une application n'est pas correctement restreinte, un attaquant peut obtenir un jeton de ressource interne en incitant un utilisateur à donner son consentement
- Le mécanisme de consentement et d'octroi d'autorisation fourni par défaut n'est pas suffisamment granulé, ce qui expose certains services internes à un risque d'exposition externe
Impact et risques
- Un utilisateur malveillant pourrait utiliser cette vulnérabilité pour accéder aux systèmes internes Microsoft et aux applications
- Si l'accès est accordé, il existe un risque de fuite de données sensibles ou d'utilisation abusive des fonctionnalités internes
Réponse et recommandations
- Les organisations doivent revoir leur gouvernance OAuth et contrôler strictement tous les processus d'attribution du consentement et des permissions
- Il faut adopter une approche basée sur le principe du moindre privilège, en limitant clairement les ressources approuvées par consentement ainsi que l'étendue des droits accordés
- Il est nécessaire de renforcer la gestion en mettant en place un audit régulier des applications OAuth et des processus de gestion du consentement
1 commentaires
Avis Hacker News
La documentation de Microsoft est un véritable cauchemar, donc qu’il y ait une vulnérabilité n’a rien de surprenant.
J’ai récemment mis en place une connexion SSO avec Entra ID, et (heureusement c’était au moins en mono-tenant) je n’avais pratiquement pas d’autre choix que d’essayer presque au hasard jusqu’à trouver les bons scopes dans le jeton d’accès et la bonne configuration pour le retour des champs supplémentaires.
Quand on cherche un guide de démarrage, on tombe sur une multitude de sous-pages, remplies du jargon obscur propre à Microsoft et de liens vers une documentation qui n’aide pas beaucoup.
Ce résultat n’a vraiment rien de surprenant.
La configuration OAuth2 et la documentation d’Entra sont complètement chaotiques.
C’est tellement confus qu’il est évident que Microsoft eux-mêmes n’arrivent pas à le faire fonctionner correctement.
Leur solution à ce problème, c’est d’ajouter « encore plus de documentation », alors qu’il est déjà difficile de lire toute la documentation existante en mode spaghetti.
D’après la documentation officielle, il n’est pas possible d’exécuter un authorization code flow avec des scopes visant plusieurs serveurs de ressources.
Pourtant, si on demande
openid $clientid/.default, ça fonctionne.À la fin du flow, on reçoit un jeton d’identité et un jeton d’accès, et le jeton d’identité montre bien que le scope OIDC a été appliqué.
Mais si on regarde le jeton d’accès,
openida disparu des scopes.On ne peut en pratique pas appeler Microsoft Graph (qui joue le rôle d’endpoint UserInfo).
Je n’ai trouvé aucune ressource expliquant correctement pourquoi ça se comporte ainsi.
L’autorisation des applications multi-tenant continue de créer des problèmes inattendus.
Je suis l’ancien PM chez Microsoft qui a travaillé sur le correctif appliqué après les résultats de recherche de Wiz.
Si je devais proposer une correction à l’article, c’est qu’il dit qu’en cas d’autorisation d’application multi-tenant, il était recommandé de ne vérifier que les claims
issoutid.En réalité, la recommandation est un peu plus complexe.
Si on ne valide que le tenant, on risque de permettre à n’importe quel service principal d’obtenir un accès autorisé.
Il faut toujours valider, dans le jeton, le sujet en plus du tenant.
Par exemple, il faut valider le jeton via la combinaison tid+oid, ou vérifier à la fois le tenant et le sujet avant d’autoriser l’accès.
Plus de détails dans la documentation officielle sur la validation des claims.
J’insiste sur une approche qui consiste à partir du principe que tous les jetons sont falsifiés.
Il faut concevoir les choses de manière sûre par défaut.
Même si ça gaspille du CPU, il faut valider tous les champs.
Une signature n’a de sens que si elle est effectivement vérifiée.
Si possible, je recommande aussi une vérification croisée avec la base de données d’identité.
Tenant, utilisateur, groupe, ressource — j’ai toujours appris aux développeurs qu’il faut tout valider soigneusement avant d’autoriser quoi que ce soit.
C’est 100 % exact.
En réalité, les ingénieurs devraient absolument lire le guide officiel.
Le guide en question est disponible ici.
Je me demande aussi si le « guide sur les choses à vérifier » est vraiment clair.
À mon avis, ce genre de chose devrait être résumé de manière simple, en Oui/Non.
Je n’ai jamais entendu parler d’un système avec une case à cocher du type « Les utilisateurs de ce groupe doivent-ils pouvoir lire les notes personnelles de tout le monde ? »
Même en mettant de côté la complexité d’Entra, il est facile de ne pas remarquer une erreur, surtout quand les innombrables tenants que Microsoft doit supporter en interne et ceux des clients tiers se retrouvent mélangés sans vraie séparation.
Ce qui est encore plus inquiétant, c’est de croire qu’un simple « jeton d’authentification » suffit à régler la sécurité.
Ce genre de site n’aurait jamais dû être exposé à Internet à l’origine (et il ne l’est plus publiquement aujourd’hui).
La sécurité réseau est vraiment reléguée au second plan, alors que c’est l’un des moyens de défense les plus efficaces.
Le plus important, c’est d’avoir plusieurs couches de défense (defense-in-depth).
On nous a dit de migrer vers le cloud, on nous a dit que c’était plus sûr qu’un réseau interne, on nous a dit que seuls les idiots gardent une équipe d’exploitation en interne.
Je suis trop vieux et trop rigide pour comprendre comment une application destinée à l’usage interne de Microsoft peut être accessible depuis l’extérieur.
Depuis 10 ans, il y a une tendance à abandonner complètement le VPN, à commencer par ce que Google a appelé « Zero Trust ».
Parce qu’une fois que quelqu’un est sur le VPN, il est devenu très difficile de lui bloquer l’accès à des données importantes.
Du coup, aujourd’hui, même les services « internes » sont exposés vers l’extérieur et chacun doit gérer ses propres permissions par couche.
Cela a aussi rendu beaucoup plus difficiles les attaques qui compromettent plusieurs services d’un seul coup.
Introduction au concept de Zero Trust
À mon avis, le vrai problème n’est pas que l’application ait été exposée sur un réseau public (autrement dit, qu’elle ne soit pas sur un intranet).
Le vrai problème, c’est que cette application (Entra ID) est multi-tenant.
Des informations d’authentification sensibles sont stockées et partagées dans la même base de données entre plusieurs tenants, y compris des attaquants malveillants.
C’est pour cela que les violations de multi-tenancy se produisent fréquemment.
Même si Entra ID a des mécanismes très robustes de vérification du tenant, il reste des vulnérabilités.
Par exemple, comme dans le billet de blog, les requêtes impliquant deux tenants ou plus (requêtes multi-tenant) sont, par défaut, très difficiles à autoriser correctement, et une petite erreur peut créer un risque global.
Par comparaison, avec une application mono-tenant, un attaquant doit impérativement être un utilisateur du tenant concerné, ce qui rend les attaques pré-authentification beaucoup plus difficiles.
On entend souvent « allez dans le cloud, c’est plus sûr que le réseau interne, pas besoin d’équipe d’exploitation dédiée », mais
le point clé, comme le montre le billet de blog, c’est que les développeurs qui implémentent l’autorisation sur le serveur de ressources ne vérifient même pas des claims de base comme issuer, audience ou subject dans le jeton.
Si ce type d’erreur se répète, être sur un intranet ne sert absolument à rien.
En fin de compte, le problème central n’est pas cloud contre auto-hébergement, mais le fait que la sécurité est intrinsèquement difficile et qu’il y a rarement un vrai cycle d’amélioration avant qu’un incident réel ne se produise.
Mettre ça sur un intranet ou derrière un VPN ne fait pas disparaître ce manque de rigueur en sécurité.
Le terme « defence in depth » serait-il passé de mode maintenant ?
Pour la plupart des entreprises, continuer à externaliser l’hébergement reste encore un bon conseil.
Même si c’est la meilleure entreprise de réparation de toitures de trois États, je n’aurais pas envie de lui confier l’exploitation complète de son site web, de son e-mail et de son système de réservation.
Les gens sur ce forum savent peut-être monter et exploiter des serveurs eux-mêmes, mais ce n’est pas le cas de « l’utilisateur moyen ».
Découvrir une vulnérabilité RCE sur un serveur de build Windows et recevoir une récompense de 0 $ est absurde.
Même si ce n’était pas un vrai zero-day mais seulement un problème de configuration, si cela permettait de compromettre l’environnement de build avec une DLL backdoor, cela pourrait provoquer une catastrophe mondiale.
Je ne connais pas bien cette UI de gestion des outils de build (elle a peut-être été ajoutée après mon départ), mais je ne pense vraiment pas que ce soit une interface conçue pour permettre de l’exécution de code à distance (RCE).
Il fallait toujours récupérer les packages depuis NuGet, et même si en apparence on pouvait spécifier n’importe quel package et n’importe quelle source, il existait en réalité une whitelist limitant cela au feed NuGet interne de Microsoft.
Le contrôle des packages NuGet était un sujet que nous prenions très au sérieux dans l’équipe d’ingénierie Windows.
L’usage de packages NuGet publics externes était totalement interdit, et s’ils devaient absolument être utilisés, il fallait les reconditionner puis les publier dans une source interne.
C’est Microsoft, donc même s’il y a beaucoup de gens brillants, quand on voit récemment la fuite d’une master key, des ingénieurs demandant à GPT d’écrire du code dans des PR, et le CEO dire que les ingénieurs backend vont disparaître,
je pense qu’on ne peut pas faire confiance à cette entreprise.
Bien sûr, la plupart des gens reconnaissent qu’ils n’ont pas vraiment d’alternative.
Mais malgré tout, y rester, c’est un peu irresponsable.
Tu parles de dotnet/runtime ?
Mon avis est vraiment simple.
Il ne faut pas utiliser Entra* (ou Azure AD, peu importe le changement de nom) pour l’AuthZ (autorisation).
Pour l’AuthN (authentification), c’est acceptable, mais l’autorisation doit être implémentée soi-même.
Si on gère seulement l’AuthZ soi-même, ce genre de problème s’évite facilement.
*- Je ne sais toujours pas pourquoi le nom a changé. On dirait qu’un administrateur Microsoft a pour devise « je renomme, donc j’existe ».
Le nom « Azure AD » crée simplement l’idée fausse qu’il s’agit d’AD hébergé sur Azure.
En réalité, c’est désormais bien plus que ça.
Implémenter l’AuthZ avec Entra est en soi acceptable.
Il suffit de cocher la case « l’affectation des utilisateurs à cette application est obligatoire » et de gérer les affectations soi-même[1].
Cela dit, c’est la seule vraie fonctionnalité d’AuthZ fournie par Entra.
Si on n’active pas l’AuthZ, s’attendre à ce qu’Entra gère automatiquement les autorisations est une erreur.
À noter qu’une autorisation simple de type « autoriser/refuser » n’a de sens que pour des applications très simples où tous les utilisateurs ont les mêmes droits.
Dans des applications plus complexes, les utilisateurs ont généralement différents niveaux d’accès, donc la vraie autorisation doit être implémentée dans l’application elle-même.
[1] Comment attribuer l’accès à une application depuis le portail d’administration
Tant qu’on y est, le fait qu’on ne puisse pas blacklister ou whitelister certains tenants dans les applications multi-tenant Entra ID est aussi un problème.
En plus, MSAL ne fonctionne même pas pour des choses comme les extensions de navigateur, donc au final les utilisateurs doivent eux-mêmes implémenter des mesures de sécurité supplémentaires pour communiquer avec Entra ID.
Vu ça, il est normal que les problèmes se multiplient.
J’aimerais qu’il y ait une fonction « cette application n’autorise l’accès qu’aux tenants suivants », mais aujourd’hui c’est seulement « mon tenant » ou « tous les tenants Azure ».
La solution de contournement que j’utilise, c’est soit de configurer l’application en « tenant unique » et d’inviter les utilisateurs d’autres tenants dans mon tenant,
soit de laisser « tous les tenants autorisés » et de gérer les vrais utilisateurs autorisés via des groupes.
Je n’ai aucune idée de savoir si cette limitation est due à une raison technique ou simplement au fait qu’aucun client important ne l’a demandée.
Azure est vraiment chaotique.
Okta a aussi ses propres problèmes, mais la documentation y est bien meilleure, et malgré un prix plus élevé, on peut gérer la sécurité complètement séparément des services Azure sans tout mélanger.
À mon avis, ça vaut largement le coût.