Heute ist die erste „Sicherheitslücke“ in dem Protokoll OAuth bekanntgeworden. Da OAuth auch die Grundlage für OpenMicroBlogging und entsprechend wichtig für identi.ca, Laconica und mnw ist, habe ich mich näher mit dem Problem beschäftigt.
Wozu OAuth?
Ein Beispiel: Wir stellen uns eine Webanwendung „imgPusher“ vor. Sie soll Benutzern beim Hochladen von Bildern in die Wikipedia helfen, in dem sie bsw. mehrere Bilder zusammen hochlädt, die Beschreibung besonders einfach eingeben lässt oder was auch immer. Zum Hochladen muss der Benutzer in der Wikipedia angemeldet sein – einerseits, weil er das Bild unter seinem Namen hochladen möchte, andererseits, weil die Wikipedia kein anonymes Hochladen von Dateien erlaubt. Das klassische Vorgehen würde darin bestehen, dass der Benutzer seinen Namen und sein Passwort bei „imgPusher“ hinterlegt, so dass sich „imgPusher“ unter seinem Namen in der Wikipedia einloggen und die Dateien hochladen kann. Dieses Vorgehen stellt jedoch ein Sicherheitsproblem dar; der Benutzer muss einem wahrscheinlich unbekannten Programm sein Passwort anvertrauen, er kann nicht nachvollziehen, ob das Passwort nicht bsw. gespeichert und dem Betreiber der Anwendung zugänglich gemacht wird.
An dieser Stelle setzt OAuth an. Wenn die Wikipedia und „imgPusher“ OAuth verwenden würden, müsste der Benutzer sein Passwort nicht weitergeben. Stattdessen würde „imgPusher“ den Benutzer nur nach seinem Benutzernamen fragen. Danach würde ein Request token generiert und der Benutzer auf eine Wikipedia-Seite weitergeleitet werden. Dort würde sichergestellt werden, dass der Benutzer gerade eingeloggt ist; danach würde Wikipedia ihn fragen, ob er „imgPusher“ wirklich die Erlaubnis erteilen möchte, Bilder unter seinem Namen hochzuladen. Wenn er diese Frage bejahen würde, würde der Benutzer zurück zu „imgPusher“ geleitet werden. Nun könnte „imgPusher“ den Request token in einem Access token umwandeln und mit diesem unter dem angegebenen Benutzernamen Bilder hochladen, ohne dass der Benutzer das Passwort auf einer dritten Seite hätte eingeben müssen. (Leider unterstützt Mediawiki OAuth noch nicht und dieses Beispiel ist rein fiktional.)
Zusammengefasst: OAuth ermöglicht Benutzern, Drittanwendungen bestimmte Aktivitäten mit ihrem Account zu erlauben. Dabei muss der Benutzer sein Passwort nicht rumgeben und kann – so der Hauptdienst es vorsieht – sogar genau festlegen, was die Drittanwendung darf und was nicht.
Das Problem
Eran Hammer-Lahav hat die heute bekanntgewordene Sicherheitslücke detailliert in seinem Blog beschrieben. Es wird deutlich, dass kein technisches, sondern ein Design-Problem besteht. Eine kurze technische Beschreibung des Problems soweit ich es verstanden habe: Ein Benutzer A, der Angreifer, verwendet „imgPusher“ aus dem obigen Beispiel. „imgPusher“ verlangt eine Authorisierung und leitet zur Wikipedia weiter. Diese URL wird von A an Person B, das Opfer, weitergegeben – möglich ist das bsw. durch einen Blogbeitrag, der eine Anwendung empfielt. B ist in der Wikipedia angemeldet oder wird jetzt dazu aufgefordert. Danach wird sie von der Wikipedia gefragt, ob sie der Anwendung „imgPusher“ wirklich erlauben möchte, Bilder unter ihrem Benutzernamen hochzuladen. B bestätigt dies und wird zurück zu „imgPusher“ gelenkt. An dieser Stelle kann A den vorher an B übergebenen Request token in einen Access token umwandeln lassen und hat damit eine „imgPusher“-Sitzung, die einen gültigen Access token für B‘s Wikipedia-Account hat.
Einfluss auf OpenMicroBlogging
OAuth ist Grundlage für OMB. Alle OMB-Nachrichten sind auch OAuth-Nachrichten. Wenn ein Benutzer die Nachrichten einer anderen Person abonniert, durchläuft er einen kompletten OAuth-Prozess. Dabei gibt er der anderen Person das Recht, auf die OAuth-Ressource „Nachricht versenden“ zuzugreifen. Ein konkretes Beispiel: Person A von Dienst X möchte die Nachrichten von Person B vom Dienst Y empfangen. Sie gibt also die Adresse ihres Profils, abstrakt „http://X/A“, auf dem Profil von B ein. Dienst Y leitet Person A auf den eigenen Server X weiter, wo sie gefragt wird, ob sie wirklich Person B vom Dienst Y abonnieren möchte. Wenn sie bestätigt, erteilt X dem Dienst Y die Erlaubnis, auf die OAuth-Ressource „Nachricht versenden“ von Person A zuzugreifen.
Die aufgedeckte Angriffsmöglichkeit stellt bei dieser Verwendung von OAuth keine Gefahr dar. Ein analoges Angriffs-Beispiel sieht wie folgt aus: Ein Benutzer C vom Dienst Y gibt Profil „http://X/A“ auf Y ein und erhält damit eine URL. Diese schiebt er X unter – hier wird bereits das erste Problem deutlich: OMB speichert in dieser URL, welcher Benutzer abonnieren möchte. Daher muss der Angriff auf eine konkrete Person ausgerichtet sein. Hat X nun diese URL aufgerufen, kommt sie zu einer Seite, auf der Dienst X (ihr eigener) sie fragt, ob sie wirklich den Benutzer C abonnieren möchte. Damit ist der Angriff gescheitert, denn X sieht, wen sie abonnieren – technisch gesprochen Zugriff auf ihre Ressourcen erlauben – soll. Aus meiner Sicht hat OAuth 2009.1 daher keinen Einfluss auf OpenMicroBlogging.
So wirklich habe ich das Angriffsszenario noch nicht durchstiegen, glaube ich. Ich als Person B bekommen von irgendwo her einen URL und werde dann von meinem OAuth unterstützendem Dienst gefragt, ob ich imgPusher erlauben möchte, mit meinem Account Dinge zu tun.
Okay, aber dazu muss dann doch im RequstToken bzw der URL der Nutzername von imgPusher drinstehen. Was sollte mich nun also dazu veranlassen, das zu genehmigen? Ich sehe, analog zu OMB, doch, wen ich dort aboniere bzw. zugreifen lasse. Wird durch diesen Aufruf dann quasi eine Antwort, das Access Token generiert und mein Dienst sendet dann eine Nachricht an den Urheber des Request Tokens mit den Daten „Nutzer B hat diesen Request Token für dich positiv beantwortet?“
Da habe ich doch das gleiche Problem wie beim OMB, ich sehe ja, wen ich da berechtigen will. Wenn ich den Request nicht selbst ausgelöst habe, sollte ich da dann nicht erlauben ;)
Der Designfehler ist jetzt, dass ich so nicht zuordnen kann, woher der Request kommt, oder? Gut, da sollte man sicher was dran machen. Die „Lücke“ funktioniert doch scheinbar aber nur im Zusammenhang mit social engineering.
Das Problem ist, dass bei klassischen OAuth-Anwendungen nicht der Consumer-Benutzername bei der Abfrage auf dem Provider angezeigt wird. Da steht nicht „Möchtest du Benutzer A auf imgPusher das Recht erteilen?“, sondern „Möchtest du imgPusher das Recht erteilen?“. Üblicherweise gibt es bei den Drittanwendungen („imgPusher“) auch gar keine Benutzernamen, sondern nur Sessions.