Wo JWT im Browser speichern? Wie kann man sich gegen CSRF schützen?


159

Ich kenne die Cookie-basierte Authentifizierung. SSL- und HttpOnly-Flag können angewendet werden, um die Cookie-basierte Authentifizierung vor MITM und XSS zu schützen. Es sind jedoch weitere besondere Maßnahmen erforderlich, um sie vor CSRF zu schützen. Sie sind nur ein bisschen kompliziert. ( Referenz )

Kürzlich habe ich festgestellt, dass JSON Web Token (JWT) als Lösung für die Authentifizierung ziemlich heiß ist. Ich kenne mich mit dem Kodieren, Dekodieren und Verifizieren von JWT aus. Ich verstehe jedoch nicht, warum einige Websites / Tutorials keinen CSRF-Schutz benötigen, wenn JWT verwendet wird. Ich habe viel gelesen und versuche, die folgenden Probleme zusammenzufassen. Ich möchte nur, dass jemand das Gesamtbild von JWT vermitteln und die Konzepte klären kann, die ich über JWT missverstanden habe.

  1. Wenn das JWT in einem Cookie gespeichert ist, entspricht es meiner Meinung nach der Cookie-basierten Authentifizierung, mit der Ausnahme, dass der Server keine Sitzungen zur Überprüfung des Cookies / Tokens benötigt. Es besteht weiterhin ein Risiko für CSRF, wenn keine besondere Maßnahme umgesetzt wird. Ist JWT nicht in einem Cookie gespeichert?

  2. Wenn das JWT in localStorage / sessionStorage gespeichert ist, gibt es kein Cookie, sodass Sie nicht vor CRSF schützen müssen. Die Frage ist, wie das JWT an den Server gesendet wird. Ich habe hier vorgeschlagen , jQuery zu verwenden, um die JWT per HTTP-Header von Ajax-Anforderungen zu senden. Also können nur die Ajax-Anfragen die Authentifizierung durchführen?

  3. Außerdem habe ich eine weitere Blogshow gefunden , in der "Authorization Header" und "Bearer" zum Senden des JWT verwendet werden. Ich verstehe die Methode, über die der Blog spricht, nicht. Könnte jemand bitte mehr über "Autorisierungsheader" und "Inhaber" erklären? Wird dadurch die vom HTTP-Header übertragene JWT ALLER Anforderungen? Wenn ja, wie wäre es mit CSRF?

Antworten:


70

JWT-Token sind beliebt, da sie in neuen Autorisierungs- und Authentifizierungsprotokollen wie OAuth 2.0 und OpenID Connect als Standard-Token-Format verwendet werden .

Wenn das Token in einem Cookie gespeichert ist, sendet der Browser es automatisch zusammen mit jeder Anforderung an dieselbe Domain. Dies ist weiterhin anfällig für CSRF-Angriffe.

Die Trägerauthentifizierung ist eines der in HTTP definierten Authentifizierungsschemata . Dies bedeutet im Grunde, dass YOUdas (JWT) -Token in den HTTP-Header der Autorisierung einer Anforderung eingefügt wird. Der Browser NOTerledigt dies automatisch für Sie, sodass er nicht zum Schutz Ihrer Website geeignet ist. Da der Browser den Header nicht automatisch zu Ihrer Anfrage hinzufügt, ist er nicht anfällig für einen CSRF-Angriff, der davon abhängt, dass Ihre Authentifizierungsinformationen automatisch an die ursprüngliche Domain gesendet werden.

Das Trägerschema wird häufig zum Schutz von Web-APIs (REST-Diensten) verwendet, die über AJAX-Aufrufe oder von mobilen Clients verwendet werden.


1
@ Timespace7 Nein, JWT-Token werden auch häufig von nativen Clients verwendet. OAuth 2.0 verfügt über Flows, die speziell auf native (mobile) Clients ausgerichtet sind. Das, was sie nicht tun, ist die implizite Browserauthentifizierung (wie Cookies oder grundlegende Authentifizierung).
MvdD

5
Ich sage, wenn Ihre API nur das JWT-Token aus dem Authorization-Header abruft, ist es nicht anfällig für CSRF. Jede Site oder API, die das Token von einem Cookie erhält, benötigt eine CSRF-Minderung.
MvdD

13
Bedeutet dies, dass wir das JWT effektiv in einem Cookie speichern können und es sicher ist, wenn wir Anfragen damit im Authorization-Header senden?
Cameronro

10
@cameronjroe Sie können es in Ihren Cookies speichern, aber nur, wenn Sie Ihre Cookies nicht zur Authentifizierung verwenden (Sie verwenden in diesem Fall Ihre Header)
Jaakko

1
AJAX-Aufrufe stammen ebenfalls vom Browser. JWT-Token werden hauptsächlich zur Authentifizierung von Web-APIs (Serving-Daten) und Cookies zur Authentifizierung von Web-Apps (Serving-Markup, Bilder, CSS und JavaScript) verwendet
MvdD

143

Wir müssen das JWT auf dem Client-Computer speichern. Wenn wir es in einem LocalStorage / SessionStorage speichern, kann es leicht von einem XSS-Angriff erfasst werden. Wenn wir es in Cookies speichern, kann ein Hacker es (ohne es zu lesen) bei einem CSRF-Angriff verwenden und sich als Benutzer ausgeben, unsere API kontaktieren und Anforderungen senden, um Aktionen auszuführen oder Informationen im Namen eines Benutzers abzurufen.

Es gibt jedoch verschiedene Möglichkeiten, die JWT in Cookies zu sichern, damit sie nicht einfach gestohlen werden können (es gibt jedoch noch einige fortgeschrittene Techniken, um sie zu stehlen). Wenn Sie sich jedoch auf LocalStorage / SessionStorage verlassen möchten, können Sie über einen einfachen XSS-Angriff darauf zugreifen.

Um das CSRF-Problem zu lösen, verwende ich in meiner Anwendung Double Submit Cookies.

Double Submit Cookies-Methode

  1. Speichern Sie JWT in einem HttpOnly-Cookie und verwenden Sie es im sicheren Modus für die Übertragung über HTTPS.

  2. Die meisten CSRF-Angriffe haben einen anderen Ursprung oder Referrer-Header mit Ihrem ursprünglichen Host in ihren Anforderungen. Überprüfen Sie also, ob Sie eine davon in der Kopfzeile haben, ob sie von Ihrer Domain stammt oder nicht! Wenn nicht, lehne sie ab. Wenn sowohl Ursprung als auch Überweiser in der Anfrage nicht verfügbar sind, machen Sie sich keine Sorgen. Sie können sich auf das Ergebnis der Ergebnisse der X-XSRF-TOKEN-Header-Validierung verlassen, die ich im nächsten Schritt erläutere.

  3. Während der Browser Ihre Cookies automatisch für die Domain der Anfrage bereitstellt, gibt es eine nützliche Einschränkung: Der auf einer Website ausgeführte JavaScript-Code kann die Cookies anderer Websites nicht lesen. Wir können dies nutzen, um unsere CSRF-Lösung zu erstellen. Um CSRF-Angriffe zu verhindern, müssen wir ein zusätzliches Javascript-lesbares Cookie erstellen, das als XSRF-TOKEN bezeichnet wird. Dieses Cookie muss erstellt werden, wenn der Benutzer angemeldet ist, und sollte eine zufällige, nicht zu erratende Zeichenfolge enthalten. Wir speichern diese Nummer auch im JWT selbst als privaten Anspruch. Jedes Mal, wenn die JavaScript-Anwendung eine Anforderung stellen möchte, muss sie dieses Token lesen und in einem benutzerdefinierten HTTP-Header senden. Da diese Vorgänge (Lesen des Cookies, Festlegen des Headers) nur in derselben Domäne der JavaScript-Anwendung ausgeführt werden können,

Angular JS macht Ihnen das Leben leichter

Glücklicherweise verwende ich Angular JS in unserer Plattform und Angular-Pakete den CSRF-Token-Ansatz, was die Implementierung für uns einfacher macht. Für jede Anfrage, die unsere Angular-Anwendung an den Server stellt, führt der Angular- $httpDienst diese Dinge automatisch aus:

  • Suchen Sie in der aktuellen Domain nach einem Cookie mit dem Namen XSRF-TOKEN.
  • Wenn dieses Cookie gefunden wird, liest es den Wert und fügt ihn der Anforderung als X-XSRF-TOKEN-Header hinzu.

Somit wird die clientseitige Implementierung automatisch für Sie erledigt! Wir müssen nur ein Cookie setzen, das XSRF-TOKENauf der aktuellen Domain auf der Serverseite benannt ist, und wenn unsere API einen Aufruf vom Client erhalten hat, muss sie den X-XSRF-TOKENHeader überprüfen und mit dem vergleichenXSRF-TOKEN im JWT vergleichen. Wenn sie übereinstimmen, ist der Benutzer real. Andernfalls handelt es sich um eine gefälschte Anforderung, die Sie ignorieren können. Diese Methode ist von der Methode "Double Submit Cookie" inspiriert.

Vorsicht

In Wirklichkeit sind Sie immer noch anfällig für XSS. Der Angreifer kann Ihnen das JWT-Token nur nicht zur späteren Verwendung stehlen, aber er kann mithilfe von XSS weiterhin Anfragen im Namen Ihrer Benutzer stellen.

localStorageUnabhängig davon, ob Sie Ihr JWT im oder nicht in Ihrem HttpOnly-Cookie speichern, können beide von XSS problemlos abgerufen werden. Sogar Ihre JWT in einem HttpOnly-Cookie kann von einem fortgeschrittenen XSS-Angriff wie der XST-Methode erfasst werden .

Zusätzlich zur Double Submit Cookies-Methode müssen Sie daher immer die Best Practices für XSS befolgen, einschließlich des Escape-Inhalts. Dies bedeutet, dass ausführbarer Code entfernt wird, der den Browser dazu veranlasst, etwas zu tun, das Sie nicht möchten. In der Regel bedeutet dies, // <![CDATA[Tags und HTML-Attribute zu entfernen, die dazu führen, dass JavaScript ausgewertet wird.

Lesen Sie hier mehr:


1
@AranDehkharghani Ja, ich denke, es verhindert Wiederholungsangriffe, insbesondere wenn Sie JWT ändern und das vorherige JWT jedes Mal ablaufen lassen, wenn es von API verwendet wird. Dies bedeutet, dass Ihr JWT wie ein Einmalkennwort (OTP) wird. Sie können JWT auf verschiedene Arten verwenden, je nachdem, wie wichtig Ihnen die Sicherheit auf Ihrer Plattform ist.
Iman Sedighi

7
Wie Sie bereits erwähnt haben, ist es nur eine Frage der Zeit, bis der Benutzer ausgenutzt wird, wenn eine Website für XSS anfällig ist. Es scheint, als würden wir erhebliche Komplexität gegen eine sehr geringe Erhöhung der Sicherheit eintauschen.
Shusson

3
@shusson Sie müssen sich um XSS- und XSRF-Angriffe kümmern, um Ihre JWT zu schützen. Ich bin nicht der Meinung, dass Sie erhebliche Komplexität gegen eine sehr geringe Erhöhung der Sicherheit eintauschen. Wenn Sicherheit wichtig ist, müssen Sie alle Anstrengungen unternehmen, um keine XSS-Schwachstellen zu haben. Diese Methode soll Ihr Token vor XSRF-Angriffen schützen. Dies bedeutet jedoch nicht, dass Sie XSS-Schwachstellen ignorieren können.
Iman Sedighi

5
@ImanSedighi Ich war mir nicht sicher, wenn Sie das JWT in einem Cookie speichern, erhöhen Sie die Komplexität und müssen sich jetzt vor XSRF schützen. Warum also nicht einfach lokalen Speicher mit Token mit kurzer Lebensdauer verwenden und sich auf die Verhinderung von XSS konzentrieren?
Shusson

2
@ Royi Namir: Spoofing durch Wireshark sollte kein Problem sein, wenn Sie ein 10-Dollar-SSL-Zertifikat verwenden! Wenn die Sicherheit der Website wichtig ist, sollten Sie die Daten verschlüsseln und das HTTPS-Protokoll verwenden.
Iman Sedighi

2

Ein weiterer Blickwinkel auf das gesamte Problem der Speicherung von JWTs:

  1. JWTs sollten niemals in Ihrem localStorage gespeichert werden
  2. Tatsächlich sollten sie nicht einmal in Ihren Cookies gespeichert werden , es sei denn, Sie können einen sehr strengen CSRF-Schutz implementieren

Überprüfen Sie dies für die Motivation

  • JWT als id_token entspricht Ihren Benutzeranmeldeinformationen
  • JWT als access_token ist wie Ihr Sitzungstoken

Die sicherste Option ist In-Memory . Kasse dies für einen tiefen Tauchgang

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.