it-swarm.com.de

Einfügen eines Kennworts in einen REST API-Aufruf

Angenommen, ich habe eine REST API, die auch zum Festlegen/Zurücksetzen von Kennwörtern verwendet wird. Nehmen wir auch an, dass dies über HTTPS-Verbindungen funktioniert. Gibt es einen guten Grund, dieses Kennwort nicht in den Aufrufpfad aufzunehmen? Sagen wir auch, ich werde es in BASE64 codieren?

Ein Beispiel wäre das Zurücksetzen eines Passworts wie folgt:

http://www.example.com/user/joe/resetpassword/OLDPASSWD/NEWPASSWD

Ich verstehe, dass BASE64 keine Verschlüsselung ist, aber ich möchte in diesem Fall nur das Passwort für das Schulter-Surfen schützen.

33

Ein guter Server protokolliert alle an ihn gesendeten Anforderungen, einschließlich URLs (häufig ohne variablen Teil nach '?'), Quell-IP, Ausführungszeit ... Möchten Sie wirklich, dass dieses Protokoll (möglicherweise von einer großen Gruppe von Administratoren gelesen) enthält kritisch sichere Informationen als Passwörter? Base64 ist kein Stopper gegen sie.

78
Netch

Was Sie vorschlagen, ist weder sicher noch ruhend.

@Netch hat das Problem mit Protokollen bereits erwähnt, aber es gibt auch ein anderes Problem, bei dem Sie Kennwörter anzeigen, die über HTTP gesendet werden. Daher ist es trivial, Kennwörter mit jeder Art von Wire Sniffer oder Man-in-the-Middle-Angriff zu erfassen.

Wenn Sie eine GET-Anforderung mit REST ausführen, stellen die verschiedenen Elemente in der URL feinkörnigere Elemente dar. Ihre URL liest sich so, als würden Sie einen NEWPASSWD-Teil eines OLDPASSWD zurückgeben, der Teil eines Rücksetzkennworts ist. Das ergibt keinen semantischen Sinn. GETs sollten nicht zum Speichern von Daten verwendet werden.

Sie sollten so etwas tun:

POST https://www.example.com/user/joe/resetpassword/
{oldpasswd:[data], newpasswd:[data]}

POST, weil Sie Daten schreiben, und https, weil Sie nicht möchten, dass sie beschnuppert werden.

(Dies ist wirklich die Low-Bar-Sicherheit. Das absolute Minimum, das Sie tun sollten.)

72
Gort the Robot

Das vorgeschlagene System weist in mehreren Bereichen Probleme auf.

Sicherheit

URL-Pfade werden häufig protokolliert. Das Einfügen von nicht verwaschenen Passwörtern in den Pfad ist eine schlechte Praxis.

[~ # ~] http [~ # ~]

Authentifizierungs-/Autorisierungsinformationen sollten im Autorisierungsheader angezeigt werden. Oder möglicherweise für browserbasierte Inhalte den Cookie-Header.

[~ # ~] rest [~ # ~]

Verben wie resetpassword in Ihrer URL sind im Allgemeinen ein klares Zeichen für ein nicht repräsentatives Statusübertragungsparadigma. Eine URL sollte eine Ressource darstellen. Was bedeutet es, resetpassword zu ERHALTEN? Oder LÖSCHEN?

[~ # ~] api [~ # ~]

Für dieses Schema muss immer das vorherige Passwort bekannt sein. Sie werden wahrscheinlich mehr Fälle zulassen wollen; z.B. Das Passwort geht verloren.


Sie können Basic- oder Digest-Authentifizierung verwenden, was gut verstandene Schemata sind.

PUT /user/joe/password HTTP/1.0
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Content-Type: text/plain
Host: www.example.com

NEWPASSWD

Es werden keine hochsensiblen Informationen in den Pfad eingefügt und es werden die Konventionen HTTP und REST) befolgt.

Wenn Sie einen anderen Autorisierungsmodus zulassen mussten (z. B. ein Token, das über einen verifizierten Kanal gesendet wurde, um das Kennwort zurückzusetzen), können Sie einfach einen anderen Autorisierungsheader verwenden, ohne etwas anderes ändern zu müssen.

60
Paul Draper

Das Problem besteht darin, Klartextkennwörter in Ihren Anforderungen zu vermeiden. Es gibt zwei Möglichkeiten, um die erholsamen Webservice-Anforderungen zu erfüllen.

1. Client-seitiges Hashing

  • Ich vermute, Sie speichern Ihre Passwörter wie e. G. Hash (Passwort + Salz)
  • Sie können das neue Passwort mit einem Salt auf der Clientseite hashen
  • Das heißt: Erstellen Sie ein neues Salt auf der Client-Seite, erstellen Sie einen Hash e. G. Hash (newPassword + newSalt)
  • Senden Sie den neu erstellten Hash und das Salz an Ihren erholsamen Webservice
  • Senden Sie das alte Passwort auch als Hash (oldPassword + oldSalt)

2. Verschlüsselung

  • Erstellen Sie eine "einmalige Schlüssel" -Ressource (otk) für einen Benutzer wie/otk/john
  • Diese Ressource gibt einen sicheren zufälligen eindeutigen einmaligen Schlüssel zurück, z. G. kbDlJbmNmQ0Y0SmRHZC9GaWtRMW0ycVJpYzhMcVNZTWlMUXN6ZWxLdTZESFRs und eine eindeutige ID e. G. 95648915125
  • Ihr erholsamer Webservice muss dieses zufällige otk für die nächste sichere Kommunikation mit der ID 95648915125 speichern
  • Verschlüsseln Sie Ihr neues und altes Passwort mit dem otk e. G. AES (aus Sicherheitsgründen sollten Sie zwei separate Otks für das alte und das neue Passwort verwenden)
  • Senden Sie die verschlüsselten Kennwörter mit der ID 95648915125 an Ihre Änderungskennwortressource
  • Eine Kombination aus otk und ID darf nur einmal funktionieren, daher müssen Sie diese Kombination löschen, nachdem Sie das Kennwort geändert haben
  • Mögliche bessere Option: Senden Sie das aktuelle/alte Passwort per Basic-Auth.

Hinweis : HTTPS ist für beide Optionen erforderlich!

4
maz258

Abgesehen von der Sicherheit besteht das Problem darin, dass es sich nicht um einen sehr RESTful-Ansatz handelt.

OLDPASSWD und NEWPASSWD stehen für nichts in Ihrer Ressourcenhierarchie und noch schlimmer, die Operation ist nicht idempotent.

Sie können also nur POST als Verb verwenden und sollten die beiden Kennwörter nicht in Ihren Ressourcenpfad aufnehmen.

4
biziclop

Was sind die Merkmale eines Vorgangs zum Zurücksetzen des Passworts?

  1. Es ändert etwas.
  2. Es gibt einen Wert, auf den es gesetzt ist.
  3. Dies dürfen nur einige Personen tun (der Benutzer, ein Administrator oder einer von beiden, möglicherweise mit unterschiedlichen Regeln, wie einer dies tun kann).

Punkt 1 bedeutet hier, dass Sie GET nicht verwenden können. Sie müssen entweder POST etwas, das die Kennwortänderungsoperation darstellt, in einen URI, der eine Ressource darstellt, die Kennwortänderungen behandelt, oder etwas, das das neue Kennwort darstellt, in einen URI einfügen Darstellen des Passworts oder Repräsentieren von etwas (z. B. des Benutzers), von dem dieses Passwort eine Funktion ist.

Im Allgemeinen würden wir POSTEN, nicht zuletzt, weil es umständlich sein kann, etwas zu setzen, das wir später nicht bekommen können, und natürlich können wir das Passwort nicht bekommen.

Punkt 2 sind daher Daten, die das neue Passwort in dem POST darstellen.

Punkt 3 bedeutet, dass wir die Anfrage autorisieren müssen. Wenn der Benutzer der aktuelle Benutzer ist, muss das aktuelle Passwort uns nachgewiesen werden (obwohl wir nicht unbedingt das aktuelle Passwort erhalten müssen, wenn es sich beispielsweise um eine Hash-basierte Herausforderung handelt wurde verwendet, um das Wissen darüber zu beweisen, ohne es zu senden).

Der URI sollte daher so etwas wie <http://example.net/changeCurrentUserPassword> Oder <http://example.net/users/joe/changePassword> Sein.

Möglicherweise möchten wir das aktuelle Kennwort in den Daten POST) sowie im verwendeten allgemeinen Autorisierungsmechanismus erhalten.

2
Jon Hanna