1 Punkte von GN⁺ 2023-10-23 | 1 Kommentare | Auf WhatsApp teilen
  • Im OAuth-Verbindungsfluss von Harvest für Outlook Calendar leitete die Callback-URL erneut zum im state-Wert angegebenen Ziel weiter, wodurch eine offene Umleitung entstand; in Kombination mit dem impliziten Grant-Flow konnten Tokens an externe URLs offengelegt werden
  • Das Problem lag nicht bei Microsoft, sondern auf der Seite der Harvest-Integration; das registrierte OAuth-redirect_uri wurde zu einer Umleitungsstation, die Nutzer an eine vom Angreifer angegebene Domain schickte
  • state ist URI-kodiertes JSON; wenn man in subdomain eine externe Domain mit Slash wie example.com/ einträgt, führt das zu einer Weiterleitung in der Form example.com/.harvestapp.com/...
  • Das PoC zeigt mit der Microsoft-OAuth-Authorize-URL und client_id=0dcef4db-36d8-4aed-9cc5-ab43e1814884, response_type=id_token, response_mode=fragment, scope=openid, wie das Fragment #id_token=... an das Weiterleitungsziel angehängt wird
  • Die Schwachstelle wurde nach einer Meldung am 23. August 2020 erst am 1. August 2023 als gepatcht bestätigt; am 22. Oktober 2023 entschuldigte sich Harvest und erklärte, die Verzögerung sei ein human error gewesen

Datenleck von Tokens im OAuth-Callback

  • Harvest ist eine Zeiterfassungssoftware, mit der Nutzer Outlook Calendar per OAuth verbinden können
  • Wenn die Autorisierung erfolgreich ist, werden Nutzer zu https://outlook-integration.harvestapp.com/auth/outlook-calendar/… weitergeleitet
  • Dieser Callback verschiebt den Nutzer anschließend erneut zu der in state angegebenen URL, wodurch eine offene Umleitung entsteht
  • Der ursprünglich bestätigte state-Wert der Callback-URL ist URI-kodiertes JSON
    • Dekodiert hat er die Form {"return_to":"/","subdomain":"hackerone295"}
    • Der Wert subdomain wird verwendet, um einen Harvest-App-Bereich wie hackerone295.harvestapp.com zu bestimmen
  • Fügt man an subdomain einen Slash an, etwa mit example.com/, wird die Callback-URL zu einer Weiterleitung auf eine externe Domain
  • Diese Callback-URL ist das in der OAuth-Anwendung registrierte redirect_uri; kombiniert man die offene Umleitung mit dem impliziten Grant-Flow, können Tokens am Weiterleitungsziel offengelegt werden
  • Die PoC-Authorize-URL verwendet die folgenden Werte
  • Nutzer werden am Ende an eine URL in der folgenden Form weitergeleitet
  • Es handelt sich nicht um eine Schwachstelle auf Microsoft-Seite

Zeit bis zum Patch nach der Meldung

  • Das Harvest-Team reagierte während der Offenlegung und des Patch-Prozesses nur sehr wenig; selbst nachdem die Schwachstelle im Triage-Prozess anerkannt worden war, dauerte die Behebung sehr lange
  • Die Schwachstelle wurde am 23. August 2020 gemeldet, und am 16. Oktober 2020 nahm Harvest erstmals Kontakt auf
  • Am 27. November 2020 erhielt der Report den Status triaged
  • Am 28. April 2022 erklärte das Unternehmen, an einem Fix zu arbeiten, und nannte zwei Wochen als Zeithorizont, tatsächlich dauerte es aber noch etwa ein weiteres Jahr bis zur Behebung
  • Am 1. August 2023 wurde bestätigt, dass die Schwachstelle gepatcht war
  • Am 21. Oktober 2023 wurde der Bericht durch einen veröffentlichten Beitrag öffentlich
  • Zum Stand dieses Tages befand sich der Report weiterhin im Status triage; obwohl die Bug-Bounty-Richtlinie eine Belohnung erwähnte, wurden weder eine Bounty noch HackerOne-Punkte ausgezahlt
  • Nachdem der Beitrag am 22. Oktober 2023 Aufmerksamkeit erhalten hatte, entschuldigte sich Harvest und erklärte in einem Kommentar, dass die Verzögerung auf human error zurückzuführen gewesen sei

1 Kommentare

 
GN⁺ 2023-10-23
Kommentare auf Hacker News
  • Als Verantwortlicher für das Bug-Bounty-Programm erkläre ich, was intern passiert ist. Ich habe mich bereits bei @0xcrypto entschuldigt und es intern erklärt, aber ich halte es für richtig, es auch hier zusammenzufassen.
    Wir konnten das Problem von Anfang an nicht vollständig reproduzieren und konnten es auch nicht schließen, weil wir Sorge hatten, etwas zu übersehen. Kurz nachdem ich zuletzt geantwortet hatte, dass ich „eine Lösung finden“ würde, kamen wir der Einschätzung näher, dass es nicht reproduzierbar sei. Dann ging eine ähnliche OAuth-bezogene Meldung ein, wodurch intern Verwirrung entstand und wir fälschlich annahmen, wir hätten sie bereits bearbeitet und weitergegeben.
    Wegen der Benachrichtigungseinstellungen habe ich Folgemeldungen verpasst, und das Issue blieb auf unbestimmte Zeit im Triage-Status, ohne Updates. Das ist keine Ausrede; ich war lange selbst als Bug-Bounty-Hunter aktiv und weiß sehr gut, wie frustrierend es ist, auf Updates eines Unternehmens zu warten. Kundensicherheit hat oberste Priorität, und was auf der Sicherheitsseite steht, entspricht der Wahrheit.

    • Fehler können passieren, aber es ist immer noch nicht erklärt, dass HackerOne trotz mehrfacher Kontaktaufnahme über drei Jahre hinweg Harvest nicht erreichen konnte.
      Außerdem ist nun unklar, wie eine Meldung behandelt werden soll, die sich nicht mehr reproduzieren lässt. Ich hätte das gern auf HackerOne weiter diskutiert, aber nach der Entschuldigung scheint wieder Funkstille eingetreten zu sein.
    • Mich würde interessieren, ob ihr letztlich glaubt, dass die Schwachstelle tatsächlich wie beschrieben funktioniert hat, und falls ja, warum die Reproduktion fehlgeschlagen ist.
    • Gut, eine direkte Erklärung zu bekommen. Auch wenn es nicht reproduzierbar war, hätte man nicht durch einen Blick in den Source Code leicht feststellen können, ob ein Open Redirect möglich ist?
    • Immerhin ist es gut, dass ihr einen Beitrag veröffentlicht habt, der zeigt, dass ihr die Sache ernst nehmt. Jeder kann Fehler machen, aber wenn man bei Fehlern keine Verantwortung übernimmt, wird die Sache größer.
    • Ich nutze Harvest gern, aber ich wünschte, ihr würdet auch die neue mobile App für iOS endlich reparieren. Es gibt inzwischen so viele kleine Probleme, dass ich aufgehört habe, sie dem Support zu melden.
      Der App-Zustand weicht häufig vom Server-Zustand ab; Serveränderungen werden erst nach einem erzwungenen Refresh sichtbar, oder Client-Änderungen werden nach dem Speichern wieder zurückgesetzt. Auch die User Experience beim Zeiterfassen ist unbequem: Buttons sind erst nach dem Scrollen sichtbar, oder die Positionen der Start-/Stopp-/Neustart-/Löschen-Buttons ändern sich ständig je nach Status des Eintrags. Die alte App war nicht hübsch, funktionierte aber problemlos.
  • Das ist ziemlich beunruhigend. Als ich Harvest genutzt habe, war der Support wirklich hervorragend: schnelle Antworten, ein sehr genaues Verständnis dafür, wie Kunden das Produkt verwenden, und ausführliche Hinweise dazu, wie man bestehende Funktionen kreativ nutzen kann.
    Bei nicht implementierten Funktionen lautete die Antwort: „Wir nehmen es ins Backlog auf, können aber nichts versprechen.“ Es heißt, es gebe 30 Personen im Engineering [1], aber ich bin mir nicht sicher, wofür diese Kapazität eingesetzt wird, da ich auch nicht gesehen habe, dass andere Funktionen schnell ausgeliefert werden.
    Als ich anfing, Spam als „Harvest-Nutzer“ zu bekommen, vermutete ich, dass die Kundenliste verkauft worden sei. Die Verantwortlichen des Unternehmens meldeten sich jedoch direkt, widersprachen entschieden und nahmen die Sache so ernst, dass sie sofort eine Untersuchung einleiteten. Das war gut.
    Am Ende wirkt aber auch das wie ein Engineering-Problem. Ich fand eine ziemlich einfache Methode heraus, mit der man aktive Kunden abschätzen konnte; auch das landete im „Backlog“ und ist seit Monaten nicht behoben. Die Korrektur wirkte äußerst trivial. Außerdem bietet MFA nur dann Schutz, wenn man sich mit Google anmeldet [2]. Trotzdem macht die App selbst ihre eigentliche Aufgabe wirklich gut.
    1: https://www.getharvest.com/about/meet-the-team
    2: https://support.getharvest.com/hc/en-us/articles/36005266713...

    • Danke für die positive Bewertung. Dass unser Support-Team hervorragend ist, dem stimme ich definitiv zu. Es ist ein kleines Team, aber es nimmt alle Angelegenheiten sehr ernst und war auch direkt an der zuvor erwähnten Untersuchung beteiligt.
      Dass die Kommunikation mit dem Melder in diesem Thread schiefgelaufen ist, war vollständig mein Fehler, und wie in meiner Antwort oben erklärt, werde ich dafür sorgen, dass so etwas nicht noch einmal passiert.
    • Ich weiß nicht, ob du es magst oder nicht. Ist das sarkastisch gemeint?
    • Die Support-Qualität war definitiv gut. Anfragen wurden immer von sehr kompetenten Leuten bearbeitet, und meist bekam ich innerhalb weniger Minuten eine Antwort.
      Einige Funktionswünsche sind sogar tatsächlich ins Produkt eingeflossen. Vielleicht lag das nicht an meinem Einfluss, aber zumindest hatten wir offenbar ähnliche Vorstellungen davon, was einen guten Zeiterfasser ausmacht.
  • Der Titel wirkt Microsoft gegenüber ziemlich unfair. Es fühlt sich so an, als solle ausgenutzt werden, dass Microsoft durch die jüngsten Authentifizierungsvorfälle im Fokus steht; als ich den Titel sah, dachte ich sofort: „Schon wieder ein MS-Breach?“
    Tatsächlich handelt es sich um Harvests Token, und wegen einer Injection-Schwachstelle im Harvest-Code wurden lediglich Harvest-App-Zugriffsrechte falsch offengelegt. Hinter jedem anderen Identity Provider wäre es genauso verwundbar gewesen.

    • Ich bin der Autor des Blogbeitrags. Ich verstehe die Bedenken und wollte Microsoft aus dem Titel herausnehmen, aber mir fiel keine passende Formulierung ein.
      Die Schwachstelle betrifft nämlich nur die OAuth-Implementierung für die Verknüpfung von Microsoft-Konten. Der ursprüngliche Titel lautete „Microsoft OAuth token leak via open redirect in Harvest App“, später habe ich ihn in „Microsoft Account's OAuth tokens leaking via open redirect in Harvest App“ geändert. Ich bin weiterhin offen dafür, ihn zu ändern, und nehme Vorschläge an.
    • Ich dachte dasselbe. Ich fragte mich sogar, ob der Artikel überhaupt verstanden hat, wie OAuth funktioniert, wenn er das als MS-Token bezeichnet.
  • RFC 6749 behandelt ausführlich, wie Authorization Server solche Angriffe verhindern können.
    Authorization Server müssen für öffentliche Clients zwingend die Registrierung von Redirect-URIs verlangen; für vertrauliche Clients wird dies ebenfalls empfohlen. Wenn in der Anfrage eine Redirect-URI angegeben ist, muss der Authorization Server sie gegen den registrierten Wert prüfen.
    Daher frage ich mich, wie das möglich war, wo die Harvest-App doch wohl keine bösartige redirect_uri registriert hatte. Ignoriert der Microsoft-OAuth-Server beim Vergleich mit den registrierten Redirect-URIs des OAuth-Clients die URL-Parameter innerhalb der redirect_uri?

    • Es sieht so aus, als hätten sie einen zweiten Redirect obendrauf gesetzt und ihn in den Parameter state gepackt. Vermutlich sollte damit an eine beliebige Stelle weitergeleitet werden.
      Der beabsichtigte Ablauf war wohl: zur Harvest-Authentifizierungs-URL gehen → Weiterleitung zur Microsoft-Authentifizierungs-URL mit redirect_uri=registered_uri und state=some_encoded_final_uri → der Nutzer gibt seine Zugangsdaten ein → Weiterleitung zur registrierten URI → state auslesen und erneut zu der darin enthaltenen URI weiterleiten.
      Auch dieser Angriff leitet weiterhin zu einer erlaubten URI weiter, aber dieser Endpoint liest state aus und reicht die Antwort/das Token unverändert weiter. Es gab drei Fehler: Missbrauch von state, falls man es schon missbraucht, state nicht zu verschlüsseln und zu validieren, und Implicit Grant aktiviert zu haben. Falls das nötig war, hätte man dafür eine separate Registrierung mit eingeschränktem Zweck anlegen sollen.
    • Die redirect_uri von Harvest ist bei Microsoft registriert. Nachdem der Microsoft-OAuth-Server zu Harvest weitergeleitet hatte, implementierte Harvest auf Basis der Daten in state eine eigene Weiterleitung.
  • Implicit Grant ist aus genau solchen Gründen, wie in diesem Beitrag zu sehen, ziemlich furchtbar.
    Nebenbei: In der kommenden OAuth-2.1-Spezifikation soll er entfernt werden: https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-09.htm...

    • War das nicht schon seit etwa 6 Jahren zur Abschaffung vorgesehen? CORS hat diesen Anwendungsfall ersetzt, also gibt es keinen Grund, ihn in der neuen Spezifikation zu behalten.
  • Dass die Behebung der Schwachstelle 3 Jahre gedauert hat? Von August 2020 bis August 2023 – ich kenne die Größe des Harvest-Teams nicht, aber das wirkt trotzdem völlig absurd.

    • Wie in vielen Unternehmen dürfte es mit niedriger Priorität im Backlog gelandet sein, ein paar Jira-Aufräumrunden und Reorganisationen durchlaufen haben und schließlich später wiederentdeckt und behoben worden sein.
    • Ich bin aus dem Harvest-Sicherheitsteam. Wie ich auch in einem anderen Kommentar geantwortet habe: Im Wesentlichen konnten wir es nicht reproduzieren, und es gab auch keinen expliziten Fix. Allerdings blieb ein Issue, der hätte geschlossen werden sollen, wegen meines menschlichen Fehlers im Status Triage.
  • Ich würde mir wünschen, dass ein OAuth-Experte dieses Problem etwas genauer erklärt. Ich habe den Blog mehrmals gelesen, verstehe die eigentliche Schwachstelle aber immer noch nicht.
    Nach meinem sehr begrenzten OAuth-Verständnis bittet die Harvest-App Microsoft darum, den Nutzer zu verifizieren; Microsoft verifiziert den Nutzer und leitet bei Erfolg zur Callback-URL weiter, wobei das Access Token im Antwortkörper übergeben wird.
    Hat der Blogautor in diesem Fall nicht einfach nur eine selbst gebaute URL erstellt, bei der die Rückgabe-URL nicht die echte Rückgabe-URL ist, sondern zu example.com führt?

    • Genau. Der Blogautor hat so eine selbst gebaute URL erstellt. Allerdings liegt die Callback-URL in der Angriffs-URL auf der Domain harvestapp, und der vom Angreifer kontrollierte Teil befindet sich in state, das aus Sicht des OAuth-Servers weitgehend undurchsichtig ist.
      Mit dieser URL kann man jemandem einen Link zu login.microsoftonline.com schicken, eine Login-Aufforderung „Bei Harvest anmelden“ anzeigen lassen und danach kann der Angreifer echte Berechtigungen im Zusammenhang mit dem Harvest-Konto erhalten.
      Normalerweise ist das nicht möglich. Ein Angreifer kann zwar eine neue App registrieren, die zu example.com weiterleitet, aber dann erhält er kein Access Token mit Harvest-bezogenen Berechtigungen, also ist das nutzlos.
      Die OAuth-App auf Microsoft-Seite hat eine gültige Allowlist für Redirects, daher würde ein Versuch wie login.microsoftonline.com/authorize?client_id=$harvestAppID&redirect_uri=attacker.com bei Microsoft einen Fehler auslösen. Der Angriff ist möglich, weil eine gültige URL unter outlook-integration.harvestapp.com das Access Token entgegennimmt und anschließend zur Angreifer-Website weiterleitet – samt Access Token.
    • Die Schwachstelle lag bei outlook-integration.harvestapp.com. Als state wurde ein JSON-Objekt verwendet, das Anweisungen enthielt, die nach einem erfolgreichen OAuth2-Callback auszuführen waren.
      Die Eigenschaft subdomain wurde genutzt, um den Browser auf eine Subdomain von harvestapp.com weiterzuleiten und dabei #id-token zu übergeben. Das Problem war, dass der Wert von subdomain unverändert in die folgende URL eingefügt wurde:
      https://${subdomain}.harvestapp.com/...#id-token=...
      Wenn man im JSON-Payload subdomain auf einen Wert wie attacker-controlled.com/ mit angehängtem Slash setzt, wird die URL zu https://attacker-controlled.com/.harvestapp.com/...#id-token=.., und der Browser wechselt auf eine andere Domain, wobei das Token offengelegt wird.
    • Microsoft prüft, ob die Rückgabe-URL in der von Harvest angegebenen Allowlist steht. Harvest hat vermutlich, um mehrere Instanzen der Software zu unterstützen, darüber einen eigenen Redirect-Mechanismus ergänzt, aber die Redirect-Eingaben nicht korrekt bereinigt.
      Daher ist das kein inhärentes Problem von OAuth selbst, sondern eine schlechte Implementierung.
    • Genau weiß ich es nicht, aber ich sehe das Problem darin, dass Harvest alle URLs als Callback-URL zugelassen hat. Microsoft muss mitgeteilt werden, dass nur bestimmte URLs als Callback erlaubt sind.
      Statt beim Einrichten des Workflows eine echte Liste vertrauenswürdiger Callback-URLs anzulegen, haben sie möglicherweise Wildcards in der Allowlist für Callback-URLs verwendet. Ich könnte auch völlig danebenliegen.
  • Ich verstehe nicht, warum man drei Jahre gewartet hat. Eine Frist vor der Veröffentlichung von 90 Tagen reicht aus.

    • Wenn extrem große Änderungen nötig sind und ein ziemlich großes Team den Großteil seiner Arbeitszeit auf dieses Problem ansetzt, kann es auch länger als 90 Tage dauern. Oder es gibt bereits eine Lösung, aber wegen der Benachrichtigung der Kunden muss sie nach einem bestimmten, relativ kurzen Zeitplan ausgerollt werden.
      Solche zusätzlichen Aufschübe sollten allerdings von den Forschern bzw. deren Anwälten/Vertretern gewährt werden. Das ist die Art von Bitte, die ein Unternehmen bei einem außergewöhnlich großen Fall in gutem Glauben stellen kann.
  • Wenn HackerOne zulässt, dass Unternehmen solche Dinge drei Jahre liegen lassen, scheint es seine Rolle nicht richtig zu erfüllen.

    • HackerOne ist von den Unternehmen abhängig, die Bug-Bounty-Programme betreiben. Wie stark sie eingebunden sind, hängt stark von den gebuchten Services ab, etwa davon, ob sie die Triage übernehmen.
      Auf der einfachsten Stufe stellen sie lediglich eine Plattform zur Offenlegung von Schwachstellen sowie standardisierte Rechtstexte bereit, damit Forscher nicht vom Legal-Team verklagt werden.
      In den meisten Fällen lehnen Unternehmen Anfragen zur Veröffentlichung ab. Wenn Forscher ohne Erlaubnis veröffentlichen, verstoßen sie gegen die Vereinbarungen mit HackerOne und dem Unternehmen und setzen sich rechtlicher Haftung aus. In diesem Fall scheint das Unternehmen der Veröffentlichung zugestimmt zu haben; auch wenn die Reaktion sehr langsam war, ist das meiner Ansicht nach anzuerkennen.
      Ich persönlich hatte auch schon mehrfach Bugs mit vierstelligen Prämien, die länger als ein Jahr nicht behoben wurden, habe das aber nicht HackerOne angelastet.
    • Ich habe auf Unternehmensseite schon HackerOne-Issues betreut, und ein HackerOne-Teilnehmer hat wiederholt gegen die Regeln von HackerOne selbst verstoßen. Es gab Verstöße gegen Veröffentlichungsfristen, falsche Social-Media-Posts über den Bug und sogar Drohungen gegen Mitarbeiter.
      HackerOne hat das nicht interessiert. Obwohl wir mehrfach darauf hingewiesen haben, dass diese Person gegen ihre Regeln verstößt, hieß es, man könne nichts tun.
      Es wirkte, als sei ein Unternehmen, das einmal auf Normalbetrieb ausgelegt war, auf eine Minimalbesetzung zusammengeschrumpft worden, bei der Support-Mitarbeiter ohne Befugnisse Fragen beantworten. Das ist schon eine Weile her, also kann es heute anders sein, aber damals war das mein Eindruck.
    • Von den drei Parteien — HackerOne, dem Unternehmen und dem Forscher, der den Bug gefunden hat — hat das Unternehmen alle Hebel in der Hand.
      Wenn Unternehmen das Gefühl bekommen, dass HackerOne Grenzen überschreitet und entscheidet, was es dem Unternehmen „erlaubt“, zu tun, werden sie HackerOne einfach verlassen und interne Lösungen aufbauen.
    • Vielleicht braucht es Bewertungen von Unternehmen, damit man schlechte Unternehmen meiden kann, die Dinge jahrelang verschleppen und nicht einmal zahlen.
  • Ich verstehe nicht, warum dieses Issue nicht an Microsoft weitergeleitet wurde. Microsoft hätte die Zugriffsrechte dieser OAuth-Anwendung entziehen können, bis das Problem behoben ist.
    Allerdings dürfte es bei Microsoft Tausende ähnlich schlechte Implementierungen geben, die per OAuth angebunden sind.

    • Ich wusste nicht, dass so etwas möglich ist. Persönlich wäre ich wohl nie auf diese Idee gekommen.