1 points par GN⁺ 2023-10-23 | 1 commentaires | Partager sur WhatsApp
  • Dans le flux de connexion OAuth d’Outlook Calendar de Harvest, l’URL de callback redirigeait à nouveau vers la destination de la valeur state, créant une redirection ouverte qui, combinée au flux d’autorisation implicite, pouvait exposer le jeton à une URL externe
  • Le problème ne venait pas de Microsoft mais de l’intégration Harvest, où le redirect_uri OAuth enregistré devenait un point de passage de redirection envoyant l’utilisateur vers un domaine choisi par l’attaquant
  • state est un JSON encodé en URI, et si l’on met un domaine externe avec une barre oblique comme example.com/ dans subdomain, la redirection prend la forme example.com/.harvestapp.com/...
  • La preuve de concept montre, depuis l’URL d’autorisation OAuth de Microsoft, un flux utilisant client_id=0dcef4db-36d8-4aed-9cc5-ab43e1814884, response_type=id_token, response_mode=fragment et scope=openid, dans lequel le fragment #id_token=... est ajouté à la cible de redirection
  • La faille a été signalée le 23 août 2020, un correctif a été confirmé le 1er août 2023, puis Harvest a présenté ses excuses le 22 octobre 2023 en expliquant que le retard relevait d’une erreur humaine

Fuite de jeton dans le callback OAuth

  • Harvest est un logiciel de suivi du temps qui permet aux utilisateurs de connecter Outlook Calendar via OAuth
  • Une fois l’autorisation réussie, l’utilisateur est redirigé vers https://outlook-integration.harvestapp.com/auth/outlook-calendar/…
  • Ce callback redirige ensuite l’utilisateur vers l’URL fournie dans state, ce qui provoque au passage une redirection ouverte
  • La valeur state observée dans l’URL de callback d’origine est un JSON encodé en URI
    • Une fois décodée, elle prend la forme {"return_to":"/","subdomain":"hackerone295"}
    • La valeur subdomain sert à déduire un espace d’application Harvest comme hackerone295.harvestapp.com
  • Si l’on ajoute une barre oblique à subdomain, par exemple example.com/, l’URL de callback redirige alors vers un domaine externe
  • Cette URL de callback est le redirect_uri enregistré dans l’application OAuth ; en combinant cette redirection ouverte avec le flux d’autorisation implicite, le jeton peut être exposé à la cible de redirection
  • L’URL d’autorisation de la preuve de concept utilise les valeurs suivantes
  • L’utilisateur est finalement redirigé vers une URL de la forme suivante
  • Il ne s’agit pas d’une vulnérabilité côté Microsoft

Le temps écoulé entre le signalement et le correctif

  • L’équipe Harvest a très peu répondu durant la divulgation et le processus de correction, et malgré la reconnaissance de la faille au triage, la correction a pris beaucoup de temps
  • La faille a été signalée le 23 août 2020, et Harvest a pris contact pour la première fois le 16 octobre 2020
  • Le 27 novembre 2020, le rapport est passé à l’état triaged
  • Le 28 avril 2022, l’entreprise a indiqué qu’un correctif était en cours et a avancé un délai estimé à 2 semaines, mais la correction effective a encore pris environ un an de plus
  • Le 1er août 2023, le correctif de la faille a été confirmé
  • Le 21 octobre 2023, le rapport a été rendu public via un billet
  • À cette date, le rapport était toujours à l’état triage et, bien que la politique de bug bounty mentionne une récompense, aucune prime ni aucun point HackerOne n’ont été attribués
  • Après que le billet a attiré l’attention le 22 octobre 2023, Harvest a expliqué et présenté ses excuses pour le retard dans un message indiquant qu’il s’agissait d’une erreur humaine

1 commentaires

 
GN⁺ 2023-10-23
Avis de Hacker News
  • En tant que responsable du programme de bug bounty, je vais expliquer ce qui s’est passé en interne. J’ai déjà présenté mes excuses à @0xcrypto et donné des explications en interne, mais il me semble juste de les résumer ici aussi
    Dès le départ, nous n’avons pas réussi à reproduire complètement le problème, et nous ne pouvions pas non plus le clore de peur de passer à côté de quelque chose. Juste après ma dernière réponse indiquant que j’allais « trouver une solution », nous étions proches de conclure à une impossibilité de reproduction, et l’arrivée d’un signalement similaire lié à OAuth a créé une confusion en interne : j’ai cru à tort que le dossier avait déjà été traité et transmis
    À cause de la configuration des notifications, j’ai manqué les messages de suivi, et le ticket est resté indéfiniment en statut Triage, sans mise à jour. Ce n’est pas une excuse ; ayant moi-même longtemps été chasseur de bugs, je sais très bien à quel point il est frustrant d’attendre des nouvelles d’une entreprise. La sécurité des clients est notre priorité absolue, et ce qui est indiqué sur la page sécurité est exact

    • Des erreurs peuvent arriver, mais cela n’explique toujours pas pourquoi, malgré plusieurs contacts avec HackerOne pendant 3 ans, HackerOne n’a pas réussi à joindre Harvest
      De plus, on ne sait toujours pas comment sera traité un signalement qui n’est désormais plus reproductible. J’aurais aimé en discuter davantage sur HackerOne, mais après le message d’excuses, cela semble être redevenu un silence radio
    • Je me demande si vous pensez au final que la vulnérabilité fonctionnait réellement de la manière décrite, et si oui, pourquoi vous n’avez pas réussi à la reproduire
    • C’est appréciable d’avoir une explication directe. Même si la reproduction n’a pas fonctionné, il me semble qu’il aurait été facile de vérifier dans le code source si une redirection ouverte était possible
    • C’est déjà une bonne chose d’avoir publié un message montrant que le sujet est pris au sérieux. Tout le monde peut faire des erreurs, mais si l’on n’en assume pas la responsabilité quand elles arrivent, les choses prennent de l’ampleur
    • J’utilise Harvest avec satisfaction, mais j’aimerais vraiment que la nouvelle app mobile iOS soit corrigée. Il y a tellement de petits problèmes que j’ai même arrêté de les signaler au support
      L’état de l’app est souvent désynchronisé de celui du serveur ; les changements côté serveur n’apparaissent qu’après un rafraîchissement forcé, ou bien des changements côté client sont annulés après enregistrement. L’expérience de suivi du temps est aussi pénible : certains boutons ne sont visibles qu’en faisant défiler, et l’emplacement des boutons démarrer/arrêter/redémarrer/supprimer change constamment selon l’état de l’élément. L’ancienne app n’était pas très jolie, mais elle fonctionnait sans problème
  • C’est assez inquiétant. Quand j’ai utilisé Harvest, le support était vraiment excellent : réponses rapides, compréhension fine de la façon dont les clients utilisaient le produit, et explications détaillées sur des manières créatives d’exploiter les fonctionnalités existantes
    Pour les fonctionnalités non implémentées, la réponse était : « nous l’ajouterons au backlog, mais sans garantie ». Il est indiqué que l’équipe d’ingénierie compte 30 personnes [1], mais je ne sais pas bien à quoi ces ressources sont consacrées. Je n’ai pas non plus vu d’autres fonctionnalités sortir rapidement
    Quand j’ai commencé à recevoir du spam en tant qu’« utilisateur Harvest », j’ai soupçonné qu’ils avaient vendu leur liste de clients, mais les responsables de l’entreprise se sont immédiatement impliqués, ont fermement démenti et ont lancé une enquête sans attendre. C’était un bon point
    Mais au bout du compte, cela ressemble aussi à un problème d’ingénierie. J’ai trouvé un moyen assez simple d’estimer les clients actifs, et ce sujet aussi a été mis dans le « backlog », puis n’a pas été corrigé depuis des mois. Le correctif semblait pourtant très mineur. Par ailleurs, le MFA n’est proposé que lors d’une connexion avec Google [2]. Cela dit, l’app elle-même fait vraiment très bien ce pour quoi elle est conçue
    1: https://www.getharvest.com/about/meet-the-team
    2: https://support.getharvest.com/hc/en-us/articles/36005266713...

    • Merci pour ces retours positifs. Je suis tout à fait d’accord sur le fait que l’équipe support est excellente. C’est une petite équipe, mais elle traite chaque sujet très sérieusement, et elle a été directement impliquée dans l’enquête mentionnée plus haut
      Le problème de communication avec l’auteur du signalement dans ce fil est entièrement de ma faute et, comme je l’ai expliqué dans la réponse en haut, je ferai en sorte que cela ne se reproduise pas
    • Je n’arrive pas à savoir si tu aimes ou si tu détestes. C’est sarcastique ?
    • La qualité du support était clairement bonne. Les demandes étaient toujours traitées par des personnes très compétentes, et je recevais généralement une réponse en quelques minutes
      Certaines demandes de fonctionnalités ont même fini dans le produit. Ce n’était peut-être pas grâce à moi, mais au moins nous semblions partager la même vision d’un bon outil de suivi du temps
  • Le titre me paraît assez injuste envers Microsoft. On dirait qu’il cherche à profiter de l’attention récente portée à Microsoft à cause d’incidents d’authentification, et en voyant le titre, ma première réaction a été : « encore une compromission chez MS ? »
    En réalité, il s’agit du token de Harvest, et seule l’autorisation d’accès à l’app Harvest a été exposée à tort à cause d’une vulnérabilité d’injection dans le code de Harvest. Cela aurait été tout aussi vulnérable derrière n’importe quel autre fournisseur d’identité

    • Je suis l’auteur du billet de blog. Je comprends l’inquiétude et j’ai essayé de retirer le nom de Microsoft du titre, mais je n’ai pas trouvé de formulation satisfaisante
      Cette vulnérabilité n’affecte que l’implémentation OAuth utilisée pour la connexion des comptes Microsoft. Le titre original était « Microsoft OAuth token leak via open redirect in Harvest App », puis je l’ai modifié en « Microsoft Account's OAuth tokens leaking via open redirect in Harvest App ». Je suis toujours prêt à le changer et j’accepte volontiers les suggestions
    • J’ai pensé la même chose. Je me suis même demandé si l’article comprenait vraiment le fonctionnement d’OAuth tout en appelant ça un token MS
  • La RFC 6749 explique en détail comment un serveur d’autorisation peut empêcher ce type d’attaque.
    Le serveur d’autorisation doit obligatoirement exiger l’enregistrement des URI de redirection pour les clients publics, et il est recommandé de le faire aussi pour les clients confidentiels. Si une URI de redirection est fournie dans la requête, le serveur d’autorisation doit la valider en la comparant à la valeur enregistrée.
    Dans ce cas, je suppose que l’app Harvest n’avait pas enregistré de redirect_uri malveillant ; je me demande donc comment cela a été possible. Le serveur OAuth de Microsoft ignore-t-il les paramètres d’URL dans le redirect_uri lorsqu’il le compare à l’URI de redirection enregistrée du client OAuth ?

    • On dirait qu’ils ont superposé une seconde redirection et l’ont placée dans le paramètre state. C’était probablement destiné à rediriger vers n’importe quelle destination.
      Le flux prévu devait ressembler à ceci : aller sur l’URL d’authentification Harvest → rediriger vers l’URL d’authentification Microsoft avec redirect_uri=registered_uri et state=some_encoded_final_uri → l’utilisateur saisit ses identifiants → redirection vers l’URI enregistrée → lecture de state puis nouvelle redirection vers l’URI qu’il contient.
      Cette attaque redirige toujours vers une URI autorisée, mais cet endpoint lit state et transmet tel quel la réponse/le token. Il y a trois erreurs : usage abusif de state, absence de chiffrement et de validation de state si on voulait l’utiliser ainsi, et activation de l’octroi implicite. S’ils en avaient besoin, ils auraient dû créer un enregistrement séparé à usage limité.
    • Le redirect_uri de Harvest est bien enregistré chez Microsoft. Après que le serveur OAuth de Microsoft a redirigé vers Harvest, c’est Harvest qui a implémenté sa propre redirection à partir des données de state.
  • L’octroi implicite est assez catastrophique pour ce genre de raison, comme on le voit dans cet article.
    À titre de référence, il doit être retiré de la prochaine spécification OAuth 2.1 : https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-09.htm...

    • Il n’était pas déjà prévu de le déprécier depuis environ six ans ? CORS a remplacé cet usage, donc il n’y a aucune raison de le garder dans la nouvelle spécification.
  • Il a fallu 3 ans pour corriger la vulnérabilité ? D’août 2020 à août 2023… Je ne connais pas la taille de l’équipe Harvest, mais ça paraît quand même complètement déraisonnable.

    • Comme c’est courant dans beaucoup d’entreprises, ça a probablement été mis dans le backlog avec une faible priorité, a survécu à quelques réorganisations de Jira et restructurations d’équipe, puis a fini par être redécouvert et corrigé plus tard.
    • Je fais partie de l’équipe sécurité de Harvest. Comme je l’ai aussi répondu dans d’autres commentaires, en gros nous n’avons pas réussi à reproduire le problème et il n’y a pas eu de correction explicite. En revanche, un ticket qui aurait dû être fermé est resté en statut Triage à cause d’une erreur humaine de ma part.
  • J’aimerais qu’un spécialiste d’OAuth explique ce problème un peu plus en détail. J’ai relu le billet plusieurs fois, mais je ne comprends toujours pas la vulnérabilité réelle.
    Avec mes connaissances très limitées d’OAuth, l’app Harvest ne demande-t-elle pas à Microsoft de vérifier l’utilisateur, puis, une fois l’utilisateur validé par Microsoft, Microsoft redirige vers une URL de callback en transmettant le token d’accès dans le corps de la réponse ?
    Dans ce cas, l’auteur du billet n’a-t-il pas simplement fabriqué une URL artisanale qui fait aller l’URL de retour vers example.com au lieu de la vraie URL de retour ?

    • C’est bien ça. L’auteur du billet a fabriqué une URL de ce type. Mais l’URL de callback dans l’URL d’attaque est sur le domaine harvestapp, et la partie contrôlée par l’attaquant se trouve dans state, qui est quasiment opaque du point de vue du serveur OAuth.
      Avec cette URL, on peut envoyer à quelqu’un un lien vers login.microsoftonline.com, afficher une invite de connexion disant « se connecter à Harvest », puis permettre à l’attaquant d’obtenir de véritables autorisations liées au compte Harvest.
      Normalement, ce n’est pas possible. Un attaquant peut enregistrer une nouvelle app qui redirige vers example.com, mais il n’obtiendra alors pas de token d’accès contenant des permissions liées à Harvest, donc cela ne sert à rien.
      Côté application OAuth Microsoft, il existe une liste d’autorisation des redirections valides, donc une tentative du type login.microsoftonline.com/authorize?client_id=$harvestAppID&redirect_uri=attacker.com provoque une erreur côté Microsoft. L’attaque est possible parce qu’une URL valide de outlook-integration.harvestapp.com reçoit le token d’accès, puis redirige à son tour vers le site de l’attaquant en transmettant aussi ce token.
    • La vulnérabilité venait de outlook-integration.harvestapp.com. Après la réussite du callback OAuth2, ils utilisaient comme state un objet JSON contenant les instructions à exécuter.
      La propriété subdomain servait à rediriger le navigateur vers un sous-domaine de harvestapp.com en transmettant #id-token. Le problème est que la valeur de subdomain était injectée telle quelle dans l’URL ci-dessous :
      https://${subdomain}.harvestapp.com/...#id-token=...
      Si, dans la charge JSON, on définit subdomain avec une valeur comme attacker-controlled.com/, avec une barre oblique finale, l’URL devient https://attacker-controlled.com/.harvestapp.com/...#id-token=.., et le navigateur se rend sur un autre domaine en divulguant le token.
    • Microsoft vérifie que l’URL de retour figure dans la liste d’autorisation définie par Harvest. Harvest a probablement ajouté par-dessus son propre mécanisme de redirection pour prendre en charge plusieurs instances du logiciel, mais n’a pas correctement nettoyé les valeurs d’entrée de redirection.
      Ce n’est donc pas un problème implicite à OAuth lui-même, mais une mauvaise implémentation.
    • Je ne suis pas sûr à 100 %, mais je pense que le problème est que Harvest autorisait toutes les URL comme URL de callback. Il faut indiquer à Microsoft de n’autoriser que certaines URL précises comme callbacks.
      Lors de la configuration du workflow, au lieu de créer une vraie liste d’URL de callback de confiance, ils ont peut-être utilisé un wildcard dans la liste d’autorisation des URL de callback. Je peux aussi me tromper complètement.
  • Je ne comprends pas pourquoi ils ont attendu trois ans. Un délai de grâce avant divulgation de 90 jours suffit

    • Si cela nécessite un changement énorme et qu’une équipe assez importante y consacre la majeure partie de son temps, cela peut dépasser 90 jours. Ou bien il existe une solution, mais il faut respecter un calendrier précis et relativement court en raison de la notification des clients
      Cela dit, ce délai supplémentaire doit être accordé par le chercheur ou par son avocat/représentant. C’est le genre de chose qu’une entreprise peut demander de bonne foi pour un dossier plus important que la normale
  • Si HackerOne laisse des entreprises laisser traîner ce genre de choses pendant trois ans, j’ai l’impression qu’ils ne jouent pas correctement leur rôle

    • HackerOne dépend des entreprises qui exploitent des programmes de bug bounty. Le degré d’implication varie beaucoup selon le service fourni, par exemple selon qu’ils s’occupent ou non du triage
      Au niveau le plus basique, ils ne font que fournir une plateforme de divulgation de vulnérabilités et des formulations juridiques standard pour éviter que les chercheurs se fassent poursuivre par les équipes juridiques
      Dans la plupart des cas, les entreprises refusent les demandes de divulgation. Si le chercheur publie sans autorisation, il viole ses accords avec HackerOne et l’entreprise, et s’expose à une responsabilité juridique. Dans ce cas-ci, l’entreprise semble avoir accepté la divulgation, et même si sa réaction a été très lente, je pense que cela mérite d’être reconnu
      Personnellement, j’ai eu plusieurs fois des bugs rémunérés à quatre chiffres qui n’ont pas été corrigés pendant plus d’un an, mais je n’ai jamais considéré que c’était la faute de HackerOne
    • J’ai déjà traité des tickets HackerOne côté entreprise, et un participant HackerOne enfreignait constamment les règles de HackerOne lui-même. Il y a eu violation du calendrier de divulgation, publications mensongères sur les réseaux sociaux à propos du bug, et même menaces envers des employés
      HackerOne n’en avait rien à faire. Même après leur avoir signalé plusieurs fois que cette personne enfreignait leurs règles, ils disaient ne rien pouvoir faire
      Cela donnait l’impression d’une entreprise autrefois amenée à un fonctionnement normal, puis réduite au strict minimum, avec des agents de support sans pouvoir qui répondaient aux questions. C’était il y a assez longtemps, donc les choses ont peut-être changé depuis, mais c’est l’impression que j’en ai gardée
    • Parmi les trois parties — HackerOne, l’entreprise et le chercheur qui a trouvé le bug — c’est l’entreprise qui détient tous les leviers
      Si les entreprises ont l’impression que HackerOne dépasse les bornes et décide de ce qu’elles sont “autorisées” à faire, elles quitteront simplement HackerOne pour créer une solution interne
    • Il faudrait peut-être des avis sur les entreprises, pour pouvoir éviter celles qui sont nulles, laissent traîner les choses pendant des années et ne paient pas les primes
  • Je ne comprends pas pourquoi ce problème n’a pas été remonté à Microsoft. Microsoft aurait pu révoquer les droits d’accès de cette application OAuth jusqu’à ce que le problème soit corrigé
    Cela dit, il doit y avoir des milliers d’implémentations tout aussi mauvaises connectées à Microsoft via OAuth

    • Je ne savais pas que c’était possible. Personnellement, je crois que je n’y aurais jamais pensé