Wie kann man den OAuth-Verbraucher geheim halten und wie kann man reagieren, wenn er kompromittiert wird?

77

Bei dieser Frage geht es darum, die Sicherheitsrisiken zu verstehen, die mit der Implementierung von oauth auf einer mobilen Plattform wie Android verbunden sind. Hierbei wird davon ausgegangen, dass wir eine Android-Anwendung haben, in die der Consumer-Schlüssel / das Geheimnis im Code eingebettet ist.

Angenommen, ein Verbrauchergeheimnis wurde kompromittiert und ein Hacker hat es in den Griff bekommen. Was sind die Konsequenzen davon?

Annahmen zu
kompromittierten Verbrauchergeheimnissen Stimmt es, dass ein kompromittiertes Verbrauchergeheimnis als solches keine Auswirkungen auf die Sicherheit des Benutzers oder auf Daten hat, die bei dem OAuth-fähigen Anbieter gespeichert sind, mit dem der Benutzer interagiert hat. Die Daten selbst sind nicht gefährdet und können vom Hacker nicht abgerufen werden.

Der Hacker müsste sich ein gültiges Benutzerzugriffstoken besorgen, und das ist viel schwieriger zu bekommen.

Was könnte ein Hacker mit einem kompromittierten Verbrauchergeheimnis anfangen?
Habe ich auch Recht, wenn ich Folgendes sage:

  • Der Hacker kann eine Anwendung einrichten / veröffentlichen, die meine App imitiert.
  • Der Hacker kann Benutzer anziehen, die den OAuth-Fluss durchlaufen, und ein Zugriffstoken über den OAuth-Tanz des Hackers abrufen (unter Verwendung des kompromittierten Consumer-Schlüssels / Geheimnisses).
  • Der Benutzer könnte denken, dass er mit meiner App zu tun hat, da er während des Autorisierungsprozesses einen vertrauten Namen (Verbraucherschlüssel) sieht.
  • Wenn ein Verbraucher eine Anfrage über den Hacker ausgibt, kann der Hacker das Zugriffstoken leicht abfangen und in Kombination mit dem Verbrauchergeheimnis jetzt in meinem Namen Anfragen signieren, um Zugriff auf meine Ressourcen zu erhalten.

Auswirkungen auf
den Endbenutzer In der Annahme, dass

  • Ein Hacker hat eine Anwendung / Site unter Verwendung meines Verbrauchergeheimnisses eingerichtet
  • Einer meiner Benutzer wurde dazu verleitet, den Zugriff auf diese Anwendung / Site zu autorisieren

Folgendes könnte passieren:

  • Der Endbenutzer bemerkt möglicherweise, dass etwas faul ist, und informiert den Dienstanbieter (z. B. Google) über die schädliche App
  • Der Dienstanbieter kann dann den Verbraucherschlüssel / das Verbrauchergeheimnis widerrufen

Auswirkungen des OAuth-Verbrauchers (meiner Anwendung):
Meine App (die das Verbrauchergeheimnis enthält) müsste aktualisiert werden, da sonst nicht alle meine Kunden meine Anwendung für Anfragen in ihrem Namen autorisieren könnten (da mein Verbrauchergeheimnis dies nicht mehr tun würde) gültig sein).

Delegieren des gesamten OAuth-Verkehrs
Obwohl es möglich wäre, viele der OAuth-Interaktionen über einen Zwischenwebserver zu delegieren (OAuth-Tanz ausführen und das Zugriffstoken an den Benutzer senden), müsste man auch alle Dienstinteraktionen als Consumer-Schlüssel als Proxy verwenden Für die Unterzeichnung jeder Anfrage ist / secret erforderlich. Ist dies die einzige Möglichkeit, den Consumer-Schlüssel / das Consumer-Geheimnis außerhalb der mobilen App geheim zu halten und an einem sichereren Ort auf dem Zwischen-Webserver zu speichern?

Alternativen
Gibt es Alternativen für dieses Proxy? Ist es möglich, das Verbrauchergeheimnis auf dem Zwischenwebserver zu speichern und über einen Mechanismus zu verfügen, mit dem die Android-Anwendung (auf dem Markt veröffentlicht und ordnungsgemäß signiert) eine sichere Anforderung an den Zwischenwebserver senden kann, um das Verbrauchergeheimnis abzurufen und zu speichern intern in der App? Kann ein Mechanismus implementiert werden, der besagt, dass der Zwischenwebserver "weiß", dass dies eine offizielle Android-App ist, die das Abrufen des Verbrauchergeheimnisses anfordert, und dass der Zwischenwebserver das Verbrauchergeheimnis nur an diese bestimmte Android-App weitergibt?

ddewaele
quelle

Antworten:

53

Zusammenfassung : Ich würde einfach das Risiko eingehen und das Geheimnis in der Client-App bewahren.

Proxyserver-Alternative :

Die einzige Möglichkeit, die unten aufgeführten Probleme angemessen zu entschärfen und die Proxy-Funktion zum Laufen zu bringen, besteht darin, die gesamten neun Meter zu durchlaufen und die gesamte Geschäftslogik für den Umgang mit den Ressourcen des Webservices eines Drittanbieters auf Ihren Proxyserver zu übertragen Machen Sie die Client-App zu einem dummen Terminal mit einer reichhaltigen Benutzeroberfläche. Auf diese Weise sind die einzigen Aktionen, die die böswillige App ausführen kann, um den Proxy in seinem Namen auszuführen, nur das, was Ihre Geschäftslogik rechtmäßig benötigt.

Aber jetzt haben Sie eine ganze Reihe anderer Probleme, die sich mit Zuverlässigkeit und Skalierbarkeit befassen müssen.

Lange Überlegungen, warum ein einfacher Proxy nicht funktionieren würde :

Einige Leute denken, wenn sie mit einem Problem konfrontiert werden: „Ich weiß, ich werde meinen eigenen Proxyserver hinzufügen.“ Jetzt haben sie zwei Probleme. (mit Entschuldigung an Jamie Zawinski)

Ihre Annahmen sind weitgehend richtig. Bis zu dem Punkt, an dem Sie über Ihren eigenen Server nachdenken, ob er das Geheimnis bewahrt und die Anrufe für die Client-App weiterleitet oder ob er versucht, festzustellen, ob die App legitim ist, und ihm das Geheimnis gibt. In beiden Ansätzen müssen Sie noch das Problem lösen: "Kommt diese Anfrage von einem Code, den ich geschrieben habe?"

Lassen Sie mich wiederholen - es gibt keine Möglichkeit, auf dem Kabel zu unterscheiden, dass eine bestimmte Software ausgeführt wird. Wenn die Daten in den Nachrichten richtig aussehen, kann nichts beweisen, dass es sich um eine andere App handelt, die diese Nachricht sendet .

Letztendlich ist es mir egal, ob ich das wahre Geheimnis kenne, wenn ich eine bösartige App schreibe, solange ich jemanden, der weiß, dass es eine Arbeit für mich erledigt, dazu bringen kann. Wenn Sie also der Meinung sind, dass eine böswillige App Ihre App für OAuth-Server von Drittanbietern ausgeben kann, warum sind Sie dann sicher, dass sie Ihre App nicht für Ihren Proxy ausgeben kann?

Aber warte, da ist noch mehr. Die Domain, in der sich Ihr Proxy-Service befindet, ist Ihre Identität sowohl gegenüber Ihren Clients als auch gegenüber dem OAuth-Anbieter (wie vom OAuth-Anbieter dem Endbenutzer angezeigt). Wenn eine böswillige App Ihren Server dazu bringen kann, schlechte Dinge zu tun, wird nicht nur Ihr Schlüssel widerrufen, sondern Ihre öffentliche Webidentität wird auch nicht mehr als vertrauenswürdig eingestuft.


Ich werde mit dem Offensichtlichen beginnen - es gibt keine Möglichkeit, auf dem Draht zu unterscheiden, welche bestimmte Software ausgeführt wird. Wenn die Daten in den Nachrichten richtig aussehen, kann nichts beweisen, dass es sich um eine andere App handelt, die diese Nachricht sendet.

Somit kann jeder Algorithmus gefälscht werden, der sich auf ein auf der App gespeichertes Geheimnis stützt. Die Stärke von OAuth besteht darin, dass der App niemals die Anmeldeinformationen des Benutzers zur Verfügung gestellt werden, sondern der App eigene temporäre Anmeldeinformationen, die der Benutzer bei Bedarf widerrufen kann.

Der Schwachpunkt hierbei ist natürlich, dass eine ausreichend gute App den Benutzer dazu bringen kann, ihr zu vertrauen und die Anmeldeinformationen nicht zu widerrufen, bevor sie ihre schändlichen Taten beendet hat.

Eine Möglichkeit, dies zu mildern, ist der Ansatz von Google, 3-Bein-OAuth anstelle des Standard-2-Bein-OAuth zu verwenden. In der dreibeinigen OAuth gibt es kein vorab zugewiesenes Geheimnis, aber bei jeder Authentifizierung wird zusammen mit jedem Zugriffstoken ein neues Zugriffstoken-Geheimnis ausgegeben. Während dies letztendlich den gleichen Nachteil hat, da eine schlechte App das Token-Geheimnis der guten App aus ihrem Prozess lesen kann, muss der Benutzer den App-Zugriff jedes Mal genehmigen, wenn er ein neues Zugriffstoken benötigt.

Und das bedeutet natürlich auch, dass es für den Benutzer etwas unpraktischer und nerviger ist.

Franci Penov
quelle
Ich habe die Frage etwas bearbeitet. Ich möchte sicherstellen, dass die Annahmen, die ich in der Frage mache, korrekt sind. Ich möchte auch die Unannehmlichkeiten für die Benutzer nicht vermeiden. Ich sehe also 2 Möglichkeiten. 1. Gehen Sie einfach das Risiko ein, bewahren Sie das Geheimnis im Code auf und verschleiern Sie es. oder 2. Führen Sie das Proxy-Verfahren durch und bewahren Sie das Geheimnis auf dem Webserver auf, wo ich ziemlich sicher bin, dass es nicht kompromittiert wird. Ist das eine faire Schlussfolgerung?
Ddewaele
Ich habe eine Frage dazu. Warum ist es unmöglich zu erkennen, dass der Codeaufruf derjenige ist, den Sie geschrieben haben? Könnten Sie nicht einfach ein Token senden, das mit Ihrer App-Signatur verknüpft ist, die wiederum mit Ihrem Zertifikat verknüpft ist? Nur Ihre Apps sind mit Ihrem Zertifikat signiert und diese Datei wird trotzdem privat gehalten.
Igor Čordaš
1
Ich meine, autorisieren Sie Anrufe an Ihren Proxyserver mit dem Wert, den Sie von dieser Signatur erhalten. [] Sigs = context.getPackageManager (). GetPackageInfo (context.getPackageName (), PackageManager.GET_SIGNATURES) .signatures; für (Signatur sig: sigs) {Trace.i ("MyApp", "Signatur-Hashcode:" + sig.hashCode ()); }
Igor Čordaš
Und warum kann meine App nicht denselben Code ausführen, sondern stattdessen context.getPackageInfo()Hardcodes "com.your.app_name"?
Franci Penov
@FranciPenov Ich denke, Ihrer Antwort fehlt ein wichtiger Teil. Proxies sind aus einem anderen Grund gut; Sie können den Umfang der Anfragen reduzieren, die jemand an Dritte richten könnte. In Ihrem Proxy können Sie festlegen, welche Anrufe an Dritte zulässig sind.
Tijme