Sollte JWT in localStorage oder Cookie gespeichert werden?

94

Zum Sichern der REST-API mithilfe von JWT kann das JWT gemäß einigen Materialien (wie diesem Handbuch und dieser Frage ) entweder in localStorage oder in Cookies gespeichert werden . Nach meinem Verständnis:

  • localStorage unterliegt XSS und es wird im Allgemeinen nicht empfohlen, vertrauliche Informationen darin zu speichern.
  • Mit Cookies können wir das Flag "httpOnly" anwenden, um das Risiko von XSS zu verringern. Wenn wir jedoch die JWT von Cookies im Backend lesen wollen, sind wir CSRF unterworfen.

Basierend auf der obigen Prämisse ist es am besten, wenn wir JWT in Cookies speichern. Bei jeder Anforderung an den Server wird das JWT aus Cookies gelesen und mithilfe des Bearer-Schemas im Authorization-Header hinzugefügt. Der Server kann dann die JWT im Anforderungsheader überprüfen (anstatt sie aus den Cookies zu lesen).

Ist mein Verständnis richtig? Wenn ja, hat der oben genannte Ansatz Sicherheitsbedenken? Oder können wir überhaupt erst mit localStorage davonkommen?

pkid169
quelle
@ lrn2prgrm, da man (zustandslose) JWT- und (zustandsbehaftete) Sitzungssemantik nicht zusammen verwenden sollte.
Ozanmuyes

Antworten:

53

Ich mag die XSRF Double Submit Cookies-Methode, die in dem Artikel erwähnt wurde, den @ pkid169 sagte, aber eines sagt Ihnen dieser Artikel nicht. Sie sind immer noch nicht gegen XSS geschützt, da der Angreifer ein Skript einfügen kann, das Ihr CSRF-Cookie liest (das nicht HttpOnly ist), und dann mithilfe dieses CSRF-Tokens eine Anforderung an einen Ihrer API-Endpunkte sendet, wobei das JWT-Cookie automatisch gesendet wird.

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

Unabhängig davon, ob Sie Ihr JWT in einem localStorage oder Ihr XSRF-Token in einem nicht nur auf http basierenden Cookie speichern, kann XSS beide problemlos abrufen. Sogar Ihr JWT in HttpOnly-Cookie kann von einem fortgeschrittenen XSS-Angriff 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, dass // <! [CDATA [-Tags und HTML-Attribute entfernt werden, die die Auswertung von JavaScript bewirken.

Iman Sedighi
quelle
11
Können Sie klarstellen, wie ein JWT in HttpOnly-Cookie abgerufen werden kann? Es kann von XSRF verwendet werden, wenn das XSRF-Token durch XSS kompromittiert wird, aber kann es wirklich selbst ergriffen werden?
Jacek Gorgoń
1
Ich weiß, dass dies ein alter Beitrag ist, aber ich möchte einige Fragen stellen ... Bedeutet das, dass gut gestaltete Skripte sowohl localStorage als auch Cookies lesen können? Wenn ja, kann man davon ausgehen, dass ein JWT möglicherweise gestohlen werden kann, unabhängig davon, wo wir es in einem Browser speichern? Dann denke ich, dass es sehr riskant ist, sich nur auf eine Zeugen Jehovas zu verlassen.
Hiroki
2
"Sogar Ihr JWT in HttpOnly-Cookie kann von einem fortgeschrittenen XSS-Angriff erfasst werden." ist falsch. Der ursprüngliche Beitrag wurde bearbeitet, um dies zu korrigieren.
Java-Addict301
"Sogar Ihr JWT in HttpOnly-Cookie kann von einem fortgeschrittenen XSS-Angriff erfasst werden." Ich kann mir vorstellen, dass jemand das Cookie abruft, indem er es an seinen eigenen Server sendet. Dafür kann er fetch mit dem richtigen Wert des Anmeldeinformationsflags verwenden. Das Hauptproblem hierbei ist der CORS-Schutz, aber unter bestimmten Umständen halte ich dies für möglich.
Bartnikiewi.cz
"Inject-Skript, das Ihr CSRF-Cookie liest (das nicht HttpOnly ist)" Die Standardimplementierung von Html.AntiForgeryToken()in ASP.NET MVC verwendet ein HttpOnly-Cookie für das CSRF-Token. Ich denke, Sie sind immer noch anfällig für bestimmte XSS, aber ich dachte, das wäre erwähnenswert.
Lovethenakedgun
20

Ein rechtzeitiger Beitrag von Stormpath hat meine Punkte ziemlich genau ausgearbeitet und meine Frage beantwortet.

TL; DR

Speichern Sie die JWT in Cookies und übergeben Sie die JWT entweder bei jeder von mir erwähnten Anfrage im Authorization-Header, oder verlassen Sie sich, wie im Artikel vorgeschlagen, auf das Backend, um CSRF zu verhindern (z. B. xsrfTokenbei Angular).

pkid169
quelle
1
Hallo, ich bin mir nicht sicher, ob dies korrekt ist, aber gibt es einige besondere Nachteile bei der Verwendung von Cookies zum Speichern von JWT, wenn Sie CrossOrigin für Ihre Controller implementieren. Dies ist eine Szene, in der sich meine Server-App an einem anderen Ort befindet und wir die anrufen API davon in unserer Kunden-App, die sich beispielsweise in einer anderen Stadt befindet? Ist das nicht der Grund, warum viele Webservice-Anbieter keine Cookies verwenden?
Valik
CrossOrigin bedeutet nicht physische Standorte. Es bezieht sich auf Anfragen aus anderen Domänen. Wenn Sie sich in .net Core für die Verwendung von CORS entscheiden, geben Sie an, welche Domänen Sie zulassen möchten. welche Überschriften Sie zulassen, etc.
Brian Allan West
Dieser Beitrag von Stormpath ist nicht mehr sichtbar.
Rokit
Es ist jetzt wieder da.
Cheeze
7
  • Speichern Sie Ihr Token nicht in LocalStorage oder SessionStorage, da dieses Token aus Javascript gelesen werden kann und daher für XSS-Angriffe anfällig ist.
  • Speichern Sie Ihren Token nicht in Cookie. Cookie (mit HttpOnly-Flag) ist eine bessere Option - es ist XSS-anfällig, aber für CSRF-Angriffe anfällig

Stattdessen können Sie beim Anmelden zwei Token bereitstellen: Zugriffstoken und Aktualisierungstoken. Das Zugriffstoken sollte im Javascript-Speicher und das Aktualisierungstoken im HttpOnly-Cookie gespeichert werden. Das Aktualisierungstoken wird nur und nur zum Erstellen neuer Zugriffstoken verwendet - mehr nicht.

Wenn der Benutzer eine neue Registerkarte öffnet oder vor Ort aktualisiert wird, müssen Sie eine Anforderung ausführen, um ein neues Zugriffstoken zu erstellen, das auf dem in Cookie gespeicherten Aktualisierungstoken basiert.

Ich empfehle außerdem dringend, diesen Artikel zu lesen: https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/

Entwickler
quelle
3
Warum die zusätzliche Komplexität, wenn Sie das Aktualisierungstoken nur als Zugriffstoken behandeln können? Wie wird dieser Ansatz mehr secure I mein Zugang markieren Token als secure, samesite: strict, http-only?
Charmanter Roboter
2

Um CSRF-Angriffe zu verhindern, die vorhandene Cookies nutzen, können Sie Ihr Cookie mit der SameSiteDirektive setzen. Stellen Sie es auf laxoder ein strict.

Dies ist noch ein Entwurf und wird ab 2019 nicht von allen aktuellen Browsern vollständig unterstützt. Abhängig von der Vertraulichkeit Ihrer Daten und / oder Ihrer Kontrolle über die von Ihren Benutzern verwendeten Browser ist dies möglicherweise eine praktikable Option. Wenn Sie die Direktive mit SameSite=laxfestlegen, werden "Navigationen auf oberster Ebene verwendet, die eine 'sichere' ... HTTP-Methode verwenden".

Ian Hunter
quelle