235 Stimmen

Sicherheit von REST-Authentifizierungsverfahren

Hintergrund:

Ich entwickle das Authentifizierungsschema für einen REST-Webdienst. Dieser muss nicht "wirklich" sicher sein (es ist eher ein persönliches Projekt), aber ich möchte ihn als Übung/Lernerfahrung so sicher wie möglich machen. Ich möchte kein SSL verwenden, da ich den Aufwand und vor allem die Kosten für die Einrichtung nicht tragen möchte.

Diese SO-Fragen waren besonders nützlich, um den Einstieg zu finden:

Ich überlege, eine vereinfachte Version von Authentifizierung bei Amazon S3 (Ich mag OAuth aber für meine Bedürfnisse scheint es zu kompliziert zu sein). Ich füge eine zufällig generierte nonce die der Server der Anfrage beifügt, um Wiederholungsangriffe zu verhindern.

Um auf die Frage zurückzukommen:

Sowohl S3 als auch OAuth beruhen auf der Signierung der Anfrage-URL zusammen mit einigen ausgewählten Headern. Keiner von ihnen unterschreibt den Antrag für POST- oder PUT-Anfragen. Ist dies nicht anfällig für einen "Man-in-the-Middle"-Angriff, bei dem die URL und die Kopfzeilen erhalten bleiben und der Anfragebody durch die vom Angreifer gewünschten Daten ersetzt wird?

Es scheint, dass ich mich dagegen schützen kann, indem ich einen Hash des Anforderungskörpers in die Zeichenfolge einfüge, die signiert wird. Ist dies sicher?

173voto

Les Hazlewood Punkte 17154

In einer früheren Antwort wurde SSL nur im Zusammenhang mit der Datenübertragung erwähnt und nicht auf die Authentifizierung eingegangen.

Eigentlich geht es um die sichere Authentifizierung von REST-API-Clients. Sofern Sie nicht die TLS-Client-Authentifizierung verwenden, ist SSL allein ist KEIN brauchbarer Authentifizierungsmechanismus für eine REST-API. SSL ohne Client-Authentifizierung authentifiziert nur den Server was für die meisten REST-APIs irrelevant ist, da man eigentlich die Authentifizierung der Kunde .

Wenn Sie keine TLS-Client-Authentifizierung verwenden, müssen Sie etwas wie ein Digest-basiertes Authentifizierungsschema (wie das benutzerdefinierte Schema von Amazon Web Service) oder OAuth 1.0a oder sogar HTTP-Basic-Authentifizierung (aber nur über SSL) verwenden.

Diese Verfahren bestätigen, dass die Anfrage von einer erwarteten Person gesendet wurde. TLS (SSL) (ohne Client-Authentifizierung) stellt sicher, dass die über die Leitung gesendeten Daten unbeeinflusst bleiben. Es handelt sich um getrennte - aber sich ergänzende - Anliegen.

Für diejenigen, die es interessiert, habe ich eine SO-Frage zu folgenden Themen erweitert HTTP-Authentifizierungsschemata und ihre Funktionsweise .

60voto

mahemoff Punkte 41244

REST bedeutet, mit den Webstandards zu arbeiten, und der Standard für eine "sichere" Übertragung im Web ist SSL. Alles andere wird ziemlich kompliziert und erfordert zusätzlichen Aufwand für die Bereitstellung von Clients, die über Verschlüsselungsbibliotheken verfügen müssen.

Sobald Sie sich für SSL entschieden haben, ist im Prinzip nichts Ausgefallenes mehr für die Authentifizierung erforderlich. Sie können sich wieder an die Webstandards halten und HTTP Basic auth (Benutzername und geheimes Token, die bei jeder Anfrage mitgeschickt werden) verwenden, da dies viel einfacher ist als ein aufwändiges Signierprotokoll und im Rahmen einer sicheren Verbindung immer noch effektiv ist. Sie müssen nur sicherstellen, dass das Kennwort niemals im Klartext übertragen wird. Wenn das Kennwort also jemals über eine Klartextverbindung empfangen wird, können Sie das Kennwort sogar deaktivieren und den Entwickler per E-Mail benachrichtigen. Sie sollten auch sicherstellen, dass die Anmeldedaten nach dem Empfang nirgendwo protokolliert werden, so wie Sie auch ein normales Passwort nicht protokollieren würden.

HTTP-Digest ist ein sicherer Ansatz, da es verhindert, dass das geheime Token weitergegeben wird; stattdessen ist es ein Hash, den der Server am anderen Ende überprüfen kann. Bei weniger sensiblen Anwendungen kann dies jedoch zu viel des Guten sein, wenn Sie die oben genannten Vorsichtsmaßnahmen getroffen haben. Schließlich wird das Kennwort des Benutzers bereits im Klartext übertragen, wenn er sich anmeldet (es sei denn, Sie verwenden eine ausgeklügelte JavaScript-Verschlüsselung im Browser), und ebenso seine Cookies bei jeder Anfrage.

Beachten Sie, dass es bei APIs besser ist, wenn der Client Token - zufällig generierte Zeichenfolgen - anstelle des Passworts übergibt, mit dem sich der Entwickler bei der Website anmeldet. Der Entwickler sollte also in der Lage sein, sich bei Ihrer Website anzumelden und neue Token zu generieren, die für die API-Verifizierung verwendet werden können.

Der Hauptgrund für die Verwendung eines Tokens besteht darin, dass er ersetzt werden kann, wenn er kompromittiert wird, während sich der Besitzer des Kennworts in das Konto des Entwicklers einloggen und damit tun kann, was er will, wenn das Kennwort kompromittiert wird. Ein weiterer Vorteil von Token ist, dass Sie mehrere Token an dieselben Entwickler ausgeben können. Vielleicht, weil sie mehrere Anwendungen haben oder weil sie Token mit unterschiedlichen Zugriffsstufen benötigen.

(Aktualisiert, um die Auswirkungen einer reinen SSL-Verbindung zu berücksichtigen).

8voto

wowest Punkte 1944

Oder Sie können die bekannte Lösung für dieses Problem nutzen und SSL verwenden. Selbstsignierte Zertifikate sind kostenlos und es ist ein persönliches Projekt, oder?

5voto

ZaDDaZ Punkte 131

Wenn Sie den Hash des Textkörpers als einen der Parameter in der URL verlangen und diese URL mit einem privaten Schlüssel signiert ist, dann könnte ein Man-in-the-Middle-Angriff den Textkörper nur durch Inhalte ersetzen, die denselben Hash erzeugen würden. Dies ist zumindest bei MD5-Hash-Werten leicht zu bewerkstelligen, und wenn SHA-1 nicht mehr funktioniert, dann wissen Sie Bescheid.

Um den Body vor Manipulationen zu schützen, müsste man eine Signatur des Bodys verlangen, die ein Man-in-the-Middle-Angriff mit geringerer Wahrscheinlichkeit knacken könnte, da er den privaten Schlüssel, der die Signatur erzeugt, nicht kennt.

3voto

djsadinoff Punkte 5291

Tatsächlich ist die ursprüngliche S3-Autorisierung fait erlauben es, den Inhalt zu signieren, wenn auch mit einer schwachen MD5-Signatur. Sie können einfach die optionale Praxis durchsetzen, einen Content-MD5-Header in den HMAC (zu signierende Zeichenfolge) aufzunehmen.

http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html

Ihr neues v4-Authentifizierungsverfahren ist sicherer.

http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X