Um ehrlich zu sein, habe ich unter den Antworten keine gefunden, die die wichtigste Frage beantwortet: "Wie schützt OAuth 2 vor Dingen wie Replay-Attacken mit dem Security Token?".
Erstens gilt das von OP beschriebene Zugangsschema nur für einen der von OAuth 2.0 bereitgestellten Ströme - Berechtigungscode Erteilung . Es gibt noch andere Ströme. Eines der gemeinsamen Merkmale aller Ströme ist, dass bei erfolgreicher Authentifizierung die Der Kunde erhält ein Zugangstoken .
Wie können Sie sich vor Replay-Angriffen schützen? Das ist (mit einigen Vorbehalten) möglich, aber Sie müssen verstehen, dass dies erstens eine Reihe von Maßnahmen erfordert (die weiter unten beschrieben werden), und zweitens können Sie sich nicht einfach zu 100 % vor dieser Art von Angriffen schützen, manchmal können Sie unberechtigte Zugriffsversuche sofort stoppen, manchmal können Sie nur die Dauer eines solchen Angriffs verkürzen, wenn er stattfindet.
Was brauchen Sie also dafür?
- Signiert verwenden JWT als Ihre Spielsteine.
- Verwenden Sie eine sehr kurze Verfallszeit für Zugangstokens, 10 Minuten sind meiner Meinung nach ausreichend.
- Ihr Autorisierungsserver muss Aktualisierungs-Tokens ausgeben, was im Allgemeinen optional nach der Norm . Die Ablaufzeit von Refresh-Tokens sollte nicht zu lang sein. Für jede Situation sollte sie anders gelöst werden, zum Beispiel würde ich sie für eine Website etwas länger als eine normale Benutzersitzung festlegen. Sie können auch eine Ablaufzeit für die Sitzung implementieren, wenn der Benutzer im Leerlauf ist, aber dies gilt für die Anwendungslogik und ist im Standard nicht vorgesehen (dies ist ein recht einfacher Mechanismus, der aber nicht in den Rahmen dieser Frage passt).
- Sie müssen die ausgegebenen Aktualisierungs-Tokens in der Datenbank des Autorisierungsservers speichern. Sie müssen jedoch keine Zugriffstoken-Daten speichern, um die Vorteile von eigenständigen JWTs zu nutzen.
- Es ist ratsam, Daten über Aktualisierungs-Token während der Lebensdauer der Sitzung zu speichern, d. h. bis zu dem Zeitpunkt, an dem das Aktualisierungs-Token abläuft (es handelt sich nicht um ein Token, sondern um eine Token-Familie - mehr dazu weiter unten).
- Ergreifen Sie allgemeine Maßnahmen zum Schutz vor Token-/Sitzungsdiebstahl, die wahrscheinlich bekannt sind, darunter die folgenden: Verwenden Sie nur eine sichere Verbindung; wenn Sie Token auf der Seite des Endnutzers mit Cookies speichern, setzen Sie Cookie-Flags, um sie zu schützen, mehr Details hier einen Schutz gegen Cross-Site Request Forgery (CSRF) implementieren, mehr Details hier .
- ( Jetzt beginnt der interessanteste Teil ) Implementieren Sie die Rotation von Aktualisierungs-Token. Das bedeutet, dass jedes Mal, wenn ein Client ein Refresh-Token verwendet, um ein neues Access-Token zu erhalten (weil das Access-Token abgelaufen ist), ein neues Refresh-Token muss zusammen mit dem neuen Zugangstoken ausgestellt werden, und das alte Refresh-Token muss ungültig gemacht werden . Es könnte nur eine Markierung in der Datenbank sein, die anzeigt, dass das Aktualisierungs-Token ungültig ist.
- Jedes Mal, wenn der Autorisierungsserver ein Refresh-Token ausstellt, muss er diesem (neben anderen erforderlichen/empfohlenen) die folgenden Angaben hinzufügen:
jti
mit einer eindeutigen Token-ID und einem privaten Anspruch mit beliebigen nicht zugewiesener öffentlicher Name z.B. fid
mit eindeutiger Token-Familien-ID (innerhalb einer Sitzung). Zum Beispiel, refresh token 1
hatte jti
3c30a712-247b-4091-b692-8c3e92b83bb2
, fid
4eb44450-84e9-4fbc-830e-33935e20f7e6
nach der Ausgabe von refresh token 2
anstelle von refresh token 1
könnte es eine neue jti
f467cf40-8cd7-485e-8711-b5c657832fc6
haben aber die gleiche fid
4eb44450-84e9-4fbc-830e-33935e20f7e6
. Sie halten die gesamte Refresh-Token-Familie in der Datenbank, bis das letzte, noch gültige Token ungültig wird, z. B. bis es abläuft. *Sie können auf den fid
dann müssen Sie die gesamte Kette/Familie von Refresh-Tokens, die innerhalb derselben Sitzung ausgegeben wurden, mit Hilfe relationaler Datenbankmechanismen verknüpfen.
- Einführung einer absoluten Verfallszeit für Aktualisierungs-Token. Jedes Mal, wenn der Autorisierungsserver innerhalb der gleichen Sitzung ein neues Refresh-Token anstelle des vorherigen Refresh-Tokens ausstellt, wird der Wert von dessen
exp
Anspruch sollte die Verfallszeit des allerersten Refresh-Tokens nicht überschreiten. Zum Beispiel, wenn refresh token 1
hatte einen Wert von 1643384057
para exp
Anspruch, dann jedes nachfolgende Refresh-Token, zum Beispiel refresh token 5
sollte ebenfalls denselben Wert enthalten 1643384057
im exp
Anspruch.
- Implementierung der Erkennung der Wiederholung (Wiederverwendung) von Refresh-Token. Vielleicht haben Sie schon erraten, was als nächstes zu tun ist. Jedes Mal, wenn der Autorisierungsserver eine Anfrage zur Ausstellung eines Zugangstokens erhält, muss der Autorisierungsserver unter anderem prüfen, ob das vorgelegte Refresh-Token zu einer bestehenden Kette/Familie gehört und nicht als ungültig markiert ist. Erhält ein Autorisierungsserver ein ungültig gewordenes Aktualisierungs-Token, das zu einer Familie mit einem gültigen (neuesten) Aktualisierungs-Token gehört, MUSS er das jüngste Aktualisierungs-Token ungültig machen (keine gültigen Token mehr vorhanden) und die Ausstellung eines Zugriffstokens verweigern.
Was passiert, wenn ein Angreifer ein Token/eine Sitzung stiehlt und versucht, es/sie wiederzuverwenden? Es gibt mehrere Szenarien:
- Das Token/die Sitzung wurde vom Angreifer verwendet, bevor der Client auf Antrag eines rechtmäßigen Benutzers die Ausstellung neuer Zugangs- und Aktualisierungs-Tokens beantragte. Das heißt, der Angreifer hat es geschafft, dies zuerst zu tun. Bei der nächsten Anfrage eines rechtmäßigen Benutzers sendet der Client dann ein ungültiges Refresh-Token an den Autorisierungsserver (weil der Angreifer die Anfrage früher gestellt hat und das Refresh-Token des rechtmäßigen Benutzers ungültig wurde). Die Sitzung wird für ungültig erklärt.
- Das Token/die Sitzung wurde von einem legitimen Benutzer verwendet, und das gestohlene Token/die gestohlene Sitzung wurde später von einem Angreifer verwendet. In diesem Fall passiert das Gleiche - die Sitzung wird ungültig, ich denke, das ist verständlich.
- Es ist möglich, dass der rechtmäßige Benutzer nach dem Diebstahl des Tokens/der Sitzung keine weiteren Anfragen mehr gestellt hat, so dass der Angreifer bis zum absoluten Ablauf des Refresh-Tokens (siehe Punkt 9) Zugang hat.
Der Autorisierungsserver kann nicht wissen, wer ein rechtmäßiger Benutzer und wer ein Angreifer ist, so dass in einer solchen Situation immer das letzte (gültige) Refresh-Token ungültig gemacht wird, wodurch die Sitzung abläuft/ungültig wird. Danach kann ein rechtmäßiger Benutzer seine Identität durch Eingabe eines Kennworts überprüfen, ein Angreifer jedoch nicht.
Wenn Sie wissen, wie das funktioniert, sollten Sie Werte für den Ablauf von Token wählen, die für Ihr Projekt relevant sind.
Ich empfehle Ihnen, sich eingehender mit der verwandte Normen sowie die OAuth 2.0 Sicherheit Beste aktuelle Praxis . Dort finden Sie auch die Abschnitt Token Replay Prevention .
51 Stimmen
Oauth2 hier einfach erklärt: gist.github.com/mziwisky/10079157
4 Stimmen
Lesen Sie die Spezifikation: tools.ietf.org/html/rfc6749 Sie werden überrascht sein, wie verständlich sie ist. Es ist auch korrekt, was vielleicht gar nicht so schlecht ist.
1 Stimmen
Diese Frage und ihre (aktuellen) Antworten konzentrieren sich alle auf einen bestimmten "Grant-Typ" in OAuth 2.0 (d.h.
code
), aber es gibt andere in OAuth 2.0 definierte Grant-Typen, die für verschiedene Anwendungsfälle (z. B. nicht nutzerbezogene) relevant sind.5 Stimmen
Warum nicht "Site B" durch etwas besser lesbares wie "IdProvider Site" ersetzen?