Sicherheit von REST-Authentifizierungsschemata

228

Hintergrund:

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

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

Ich denke darüber nach, eine vereinfachte Version der Amazon S3-Authentifizierung zu verwenden (ich mag OAuth, aber es scheint für meine Anforderungen zu kompliziert zu sein). Ich füge der Anforderung eine zufällig generierte Nonce hinzu , die vom Server bereitgestellt wird, um Wiederholungsangriffe zu verhindern.

Um auf die Frage zu kommen:

Sowohl S3 als auch OAuth müssen die Anforderungs-URL zusammen mit einigen ausgewählten Headern signieren. Keiner von beiden signiert den Anforderungshauptteil für POST- oder PUT-Anforderungen. Ist dies nicht anfällig für einen Man-in-the-Middle-Angriff, bei dem die URL und die Header beibehalten und der Anforderungshauptteil durch die vom Angreifer gewünschten Daten ersetzt werden?

Es scheint, als könnte ich mich dagegen schützen, indem ich einen Hash des Anforderungshauptteils in die Zeichenfolge einbinde, die signiert wird. Ist das sicher?

dF.
quelle
6
Amazon S3 kann ein Content-MD5 als Teil der Header-Zeichenfolge enthalten, um den von Ihnen beschriebenen MITM-Angriff zu verhindern.
Laz
8
MD5 ist eine sehr schwache Hash-Funktion und von ihrer Verwendung wird seit vielen Jahren abgeraten: en.wikipedia.org/wiki/MD5 . Verwenden Sie heutzutage SHA2. MD5 ist Lippenstift auf einem Schwein mit einer Identitätskrise.
Henrik
6
Startcom bietet kostenlose SSL-Zertifikate, die keine Zertifikatswarnungen in gängigen Browsern auslösen
Plato
5
@ SeanKAnderson (schimpfen: Ich finde es absurd, wie Leute über 99,99999% s sprechen, wenn das Internet von Spionageagenturen belagert wird, die bereits 2008 VIELE Angriffe automatisiert haben - es ist eine so seltsame Art, mit einem echten Problem umzugehen - "Naaah, wird kein Problem sein; meine Oma würde es nicht hacken können"
Henrik
2
@Plato Ich würde LetsEncrypt in diesen Tagen für kostenlose SSL-Zertifikate empfehlen
Shuttle87

Antworten:

168

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

Sie fragen wirklich nach der sicheren Authentifizierung von REST-API-Clients. Sofern Sie nicht die TLS-Clientauthentifizierung verwenden, ist SSL allein KEIN praktikabler Authentifizierungsmechanismus für eine REST-API. SSL ohne Clientauthentifizierung authentifiziert nur den Server , was für die meisten REST-APIs irrelevant ist, da Sie den Client wirklich authentifizieren möchten .

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

Diese Schemata bestätigen, dass die Anforderung von einer erwarteten Person gesendet wurde. TLS (SSL) (ohne Clientauthentifizierung) stellt sicher, dass die über das Kabel gesendeten Daten nicht manipuliert werden. Sie sind getrennte - aber komplementäre - Anliegen.

Für Interessenten habe ich eine SO-Frage zu HTTP-Authentifizierungsschemata und deren Funktionsweise erweitert .

Les Hazlewood
quelle
16
Genau. Das einzige, was SSL in Bezug auf Ihre API überprüft, ist, dass der Anruf, mit dem es sich befasst, unterwegs nicht durcheinander gebracht wurde. Die API hat immer noch keine Ahnung, wer mit ihr spricht oder ob sie überhaupt Zugriff haben soll oder nicht.
Tim Gautier
1
Gute Antwort. Ich würde auch empfehlen, einen Blick auf diese hervorragenden Ressourcen zu werfen . Owasp.org/index.php/Web_Service_Security_Cheat_Sheet und owasp.org/index.php/REST_Security_Cheat_Sheet (ENTWURF)
dodgy_coder
2
Nur ein kleiner Punkt, aber die Verwendung von SSL hat auch den zusätzlichen Vorteil, dass das Abhören und Angriffe von Menschen in der Mitte verhindert werden.
dodgy_coder
@Les Hazlewood Können Sie erklären, wie die HTTP Basic-Authentifizierung über HTTP dazu beitragen kann, festzustellen, mit wem der Server weiß, mit wem er spricht?
Frühling
@Les Hazlewood hier habe ich es in einer Frage gestellt; tnx stackoverflow.com/questions/14043397/…
Frühling
60

REST bedeutet, mit den Standards des Webs zu arbeiten, und der Standard für die "sichere" Übertragung im Web ist SSL. Alles andere wird irgendwie funky und erfordert zusätzlichen Bereitstellungsaufwand für Clients, für die Verschlüsselungsbibliotheken verfügbar sein müssen.

Sobald Sie sich für SSL entschieden haben, ist für die Authentifizierung im Prinzip wirklich nichts Besonderes erforderlich. Sie können wieder Webstandards verwenden und die HTTP Basic-Authentifizierung (Benutzername und geheimes Token, die zusammen mit jeder Anforderung gesendet werden) verwenden, da dies viel einfacher als ein ausgeklügeltes Signaturprotokoll ist und im Kontext einer sicheren Verbindung immer noch wirksam ist. Sie müssen nur sicherstellen, dass das Passwort niemals über Klartext geht. Wenn das Kennwort jemals über eine Nur-Text-Verbindung empfangen wird, können Sie das Kennwort sogar deaktivieren und dem Entwickler eine E-Mail senden. Sie sollten auch sicherstellen, dass die Anmeldeinformationen beim Empfang nirgendwo protokolliert werden, genauso wie Sie kein reguläres Kennwort protokollieren würden.

HTTP Digest ist ein sicherer Ansatz, da verhindert wird, dass das geheime Token weitergegeben wird. Stattdessen ist es ein Hash, den der Server am anderen Ende überprüfen kann. Wenn Sie die oben genannten Vorsichtsmaßnahmen getroffen haben, kann dies für weniger empfindliche Anwendungen zu viel des Guten sein. Schließlich wird das Kennwort des Benutzers bereits bei der Anmeldung im Klartext übertragen (es sei denn, Sie führen eine ausgefallene JavaScript-Verschlüsselung im Browser durch), und ebenso die Cookies bei jeder Anfrage.

Beachten Sie, dass es bei APIs für den Client besser ist, Token - zufällig generierte Zeichenfolgen - anstelle des Kennworts zu übergeben, mit dem sich der Entwickler auf der Website anmeldet. Der Entwickler sollte sich also bei Ihrer Site anmelden und neue Token generieren können, die für die API-Überprüfung verwendet werden können.

Der Hauptgrund für die Verwendung eines Tokens besteht darin, dass es ersetzt werden kann, wenn es kompromittiert wird. Wenn das Kennwort kompromittiert wird, kann sich der Eigentümer beim Entwicklerkonto anmelden und alles tun, was er will. Ein weiterer Vorteil von Token besteht darin, dass Sie mehrere Token an dieselben Entwickler ausgeben können. Vielleicht, weil sie mehrere Apps haben oder weil sie Token mit unterschiedlichen Zugriffsebenen wollen.

(Aktualisiert, um die Auswirkungen der Herstellung der Verbindung nur auf SSL abzudecken.)

Mahemoff
quelle
3
Sie könnten ein GoDaddy-SSL-Zertifikat für etwa 30 US-Dollar pro Jahr bekommen, denke ich. Ich war schockiert zu sehen, wie viel die Verisign SSL-Zertifikate kosten (600 US-Dollar pro Jahr oder so, wenn ich mich richtig erinnere?), Aber die GoDaddy-Option ist durchaus machbar.
Brian Armstrong
19
Sofern Sie nicht die gegenseitige SSL / TLS-Authentifizierung verwenden und das vom Benutzer / Client verwendete Zertifikat vom Server als vertrauenswürdig eingestuft wird, haben Sie den Benutzer nicht beim Server / der Anwendung authentifiziert. Sie müssten etwas mehr tun, um den Benutzer beim Server / der Anwendung zu authentifizieren.
Pauld
5
Ryan: Die SSL-Verschlüsselung benötigt heutzutage nur sehr wenig Rechenleistung im Vergleich zu dem, was Sie zum Generieren einer Antwort mit einem Web-App-Framework wie Django oder Rails usw. verwenden würden.
Cameron Walsh
4
Zertifikate von startcom sind kostenlos und allgemein anerkannt. cacert.org ist eine offene Alternative mit weniger Anerkennung
Dima Tisnek
17
Damit wird die Frage nach der Authentifizierung nicht beantwortet.
Sam Stainsby
8

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

wowest
quelle
2
Selbstsignierte Zertifikate sind kostenlos, aber AFAIK Sie benötigen immer noch eine statische IP.
dF.
8
@dF Es ist keine statische IP erforderlich, mit Ausnahme bestimmter Lizenzanforderungen für gewerblich bezahlte Zertifikate.
Chris Marisic
Wenn Sie die Kontrolle über die Zertifikatspeicher auf beiden Seiten (Clients und Server) haben, ist dies möglicherweise eine praktikable Option, aber ... die Verwaltung und Verteilung von Zertifikaten ist in der Produktion wahrscheinlich viel komplexer als in einer Entwicklungsumgebung. Stellen Sie sicher, dass Sie die Komplexität dieser Alternative verstehen, bevor Sie sich dazu verpflichten.
Aled
5

Wenn Sie den Hash des Körpers als einen der Parameter in der URL benötigen und diese URL über einen privaten Schlüssel signiert ist, kann ein Man-in-the-Middle-Angriff den Körper nur durch Inhalte ersetzen, die den generieren gleicher Hash. Zumindest mit MD5-Hashwerten ist das jetzt einfach und wenn SHA-1 kaputt ist, erhalten Sie das Bild.

Um den Körper vor Manipulationen zu schützen, müssten Sie eine Signatur des Körpers benötigen, die bei einem Man-in-the-Middle-Angriff mit geringerer Wahrscheinlichkeit unterbrochen werden kann, da sie den privaten Schlüssel, der die Signatur generiert, nicht kennen .

ZaDDaZ
quelle
9
Es kann viel einfacher sein, eine Zeichenfolge zu erstellen, die denselben md5-Hash wie der gültige Inhalt generiert, als es sein sollte, aber es ist immer noch unerschwinglich schwierig, eine böse Version des gültigen Inhalts zu erstellen, die auf denselben Wert hasht. Aus diesem Grund wird md5 nicht mehr für Kennwort-Hashes verwendet, sondern weiterhin zum Überprüfen von Downloads.
Tim Gautier
1

Denken Sie daran, dass Ihre Vorschläge es Clients erschweren, mit dem Server zu kommunizieren. Sie müssen Ihre innovative Lösung verstehen und die Daten entsprechend verschlüsseln. Dieses Modell eignet sich nicht so gut für öffentliche APIs (es sei denn, Sie sind amazon \ yahoo \ google ..).

Wenn Sie den Inhalt des Körpers verschlüsseln müssen, würde ich Ihnen empfehlen, vorhandene Standards und Lösungen zu überprüfen, z.

XML-Verschlüsselung (W3C-Standard)

XML-Sicherheit

LiorH
quelle