Lokale Speicherung oder Cookies? JWTs sicher auf dem Client speichern

JWT (JSON Web Token) ist ein wunderbarer JSON-basierter Standard zum Erstellen von Zugriffstoken, die üblicherweise für die Authentifizierung in Client / Server-Anwendungen verwendet werden. Bei Verwendung dieser Token stellt sich die Frage, wie sie sicher im Front-End der Anwendung gespeichert werden können. Dieses Problem muss sofort behoben werden, nachdem das Token auf dem Server generiert und auf die Clientseite der Anwendung übertragen wurde. Das Material, dessen Übersetzung wir heute veröffentlichen, ist der Analyse der Vor- und Nachteile der Verwendung des lokalen Speichers des Browsers ( ) und der Cookies zum Speichern von JWTs gewidmet.







localStorage



Arten von Token



  • Zugriffstoken sind normalerweise kurzlebige JWTs, die vom Server signiert werden. Sie sind in jeder HTTP-Anforderung enthalten, die der Client an den Server stellt. Tokens werden verwendet, um Anfragen zu autorisieren.
  • Aktualisierungstoken sind normalerweise langlebige Token, die in einer Datenbank gespeichert sind und verwendet werden, um ein neues Zugriffstoken zu erhalten, wenn das vorherige Token abläuft.


Wo genau sollen die Token auf dem Client gespeichert werden?



Es gibt zwei gängige Methoden zum Speichern von Token auf dem Client: Speicher des lokalen Browsers und Cookies. Es wird viel darüber diskutiert, welche Methode besser ist. Die meisten Menschen neigen aufgrund ihrer besseren Sicherheit zu Cookies.



Vergleichen wir den lokalen Speicher und die Cookies. Unser Vergleich basiert hauptsächlich auf diesem Material und den Kommentaren dazu.



Lokaler Speicher



▍Vorteile



Der Hauptvorteil der lokalen Speicherung besteht darin, dass sie bequem zu verwenden ist.



  • Das Arbeiten mit lokalem Speicher ist sehr praktisch, hier wird reines JavaScript verwendet. Wenn Ihre Anwendung kein Backend hat und Sie sich auf APIs von Drittanbietern verlassen, können Sie diese APIs möglicherweise nicht immer anfordern, um bestimmte Cookies für Ihre Website zu setzen.
  • Bei Verwendung des lokalen Speichers ist es praktisch, mit APIs zu arbeiten, für die ein Zugriffstoken im Anforderungsheader platziert werden muss. Zum Beispiel - wie folgt : Authorization Bearer ${access_token}.


▍Nachteile



Der Hauptnachteil des lokalen Speichers ist seine Anfälligkeit für XSS-Angriffe.



  • Bei einem XSS-Angriff kann ein Angreifer seinen JavaScript-Code auf Ihrer Site ausführen. Dies bedeutet, dass ein Angreifer Zugriff auf das darin gespeicherte Zugriffstoken erhalten kann localStorage.
  • Die Quelle des XSS-Angriffs kann JavaScript-Code von Drittanbietern sein, der auf Ihrer Website enthalten ist. Dies kann beispielsweise React, Vue, jQuery, Google Analytics-Skript usw. sein. Unter modernen Bedingungen ist es fast unmöglich, eine Site zu entwickeln, die keine Bibliotheken von Drittanbietern enthält.


Kekse



▍Vorteile



Der Hauptvorteil von Cookies besteht darin, dass sie nicht über JavaScript zugänglich sind. Infolgedessen sind sie nicht so anfällig für XSS-Angriffe wie lokaler Speicher.



  • Wenn Sie ein Flag verwenden HttpOnlyund Cookies sichern, bedeutet dies, dass JavaScript nicht auf diese Dateien zugreifen kann. Das heißt, selbst wenn ein Angreifer seinen Code auf Ihrer Seite ausführen kann, kann er das Zugriffstoken nicht aus dem Cookie lesen.
  • Bei jeder HTTP-Anfrage werden automatisch Cookies an den Server gesendet.


▍Nachteile



Abhängig von den spezifischen Umständen kann es vorkommen, dass die Token in den Cookies nicht gespeichert werden können.



  • Die Größe von Cookies ist auf 4 KB begrenzt. Wenn Sie große JWTs verwenden, funktioniert das Speichern in Cookies daher nicht für Sie.
  • Es gibt Szenarien, in denen Sie keine Cookies an Ihren API-Server übergeben können. Es ist auch möglich, dass für einige APIs ein Token im Header platziert werden muss Authorization. In diesem Fall können Sie Token nicht in Cookies speichern.


XSS-Angriffe



Lokaler Speicher ist anfällig für XSS-Angriffe, da die Verwendung von JavaScript sehr einfach ist. Daher kann ein Angreifer Zugriff auf das Token erhalten und es zu seinem Vorteil nutzen. Obwohl HttpOnly-Cookies nicht über JavaScript erreichbar sind, bedeutet dies nicht, dass Sie vor XSS-Angriffen geschützt sind, indem Sie Cookies verwenden, um ein Zugriffstoken zu stehlen.



Wenn ein Angreifer seinen JS-Code in Ihrer Anwendung ausführen kann, bedeutet dies, dass er einfach eine Anfrage an Ihren Server senden kann und das Token automatisch in diese Anfrage aufgenommen wird. Ein solches Arbeitsschema ist für den Angreifer einfach nicht so bequem, da er den Inhalt des Tokens nicht lesen kann. Aber Angreifer brauchen das selten. Darüber hinaus kann es bei diesem Arbeitsschema für einen Angreifer rentabler sein, den Server über den Computer des Opfers und nicht über seinen eigenen anzugreifen.



Cookies und CSRF-Angriffe



CSRF-Angriffe sind Angriffe, bei denen ein Benutzer irgendwie gezwungen wird, eine spezielle Anfrage zu stellen. Beispielsweise akzeptiert die Site Anforderungen zum Ändern der E-Mail-Adresse:



POST /email/change HTTP/1.1
Host: site.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 50
Cookie: session=abcdefghijklmnopqrstu

email=myemail.example.com


In einer solchen Situation könnte ein Angreifer ein Formular mit einem ausgeblendeten Feld zur Eingabe einer E-Mail-Adresse erstellen, an die eine POST-Anfrage gesendet wird https://site.com/email/change. In diesem Fall werden Sitzungscookies automatisch in eine solche Anfrage aufgenommen.



Diese Bedrohung kann jedoch leicht geschützt werden, indem das Attribut SameSiteim Antwortheader und in den Anti-CSRF- Token verwendet wird.



Zwischensummen



Obwohl Cookies nicht vollständig immun gegen Angriffe sind, können Token am besten nach Möglichkeit gespeichert werden localStorage. Warum?



  • Sowohl lokaler Speicher als auch Cookies sind anfällig für XSS-Angriffe. Für einen Angreifer ist es jedoch schwieriger anzugreifen, wenn HttpOnly-Cookies verwendet werden.
  • Cookies sind anfällig für CSRF-Angriffe, aber das Risiko solcher Angriffe kann durch die Verwendung der Attribut- SameSiteund Anti-CSRF- Token verringert werden .


Cookies können auch dann verwendet werden, wenn Sie einen Header verwenden Authorization: Bearermüssen oder wenn die JWT größer als 4 KB ist. Dies steht auch im Einklang mit den OWASP- Richtlinien : „Speichern Sie Sitzungs-IDs nicht im lokalen Speicher, da die entsprechenden Daten immer über JavaScript verfügbar sind. Cookies können dabei helfen, das Risiko zu verringern HttpOnly. "



Verwenden von Cookies zum Speichern von OAuth 2.0-Token



Lassen Sie uns kurz die Möglichkeiten zum Speichern von Token auflisten:



  • Methode 1: Speichern von Token im lokalen Speicher. Diese Methode ist anfällig für XSS-Angriffe.
  • Methode 2: Speichern von Token in HttpOnly-Cookies. Diese Methode ist anfällig für CSRF-Angriffe, aber das Risiko solcher Angriffe kann verringert werden. Diese Token-Speicheroption ist etwas besser vor XSS-Angriffen geschützt als die erste.
  • Methode 3: Speichern Sie Aktualisierungstoken in HttpOnly-Cookies und greifen Sie auf Token im Speicher zu. Diese Art der Speicherung von Token ist in Bezug auf CSRF-Angriffe sicherer und etwas besser vor XSS-Angriffen geschützt.


Im Folgenden werden wir uns die dritte Methode zum Speichern von Token genauer ansehen, da sie von den drei aufgeführten am interessantesten aussieht.



Warum ist das Speichern des Aktualisierungstokens in einem HttpOnly-Cookie im Hinblick auf CSRF-Angriffe sicherer?



Ein Angreifer kann ein Formular erstellen, auf das zugegriffen wird /refresh_token. Als Antwort auf diese Anforderung wird ein neues Zugriffstoken zurückgegeben. Der Angreifer kann die Antwort jedoch nicht lesen, wenn er ein HTML-Formular verwendet. Um zu verhindern, dass ein Angreifer Abruf- oder AJAX-Anforderungen erfolgreich ausführt und Antworten liest, muss die CORS-Richtlinie des Autorisierungsservers korrekt konfiguriert sein, damit der Server nicht auf Anforderungen von nicht autorisierten Websites reagiert.



Wie richten Sie es ein?



Schritt 1: Zugriffstoken zurückgeben und Token aktualisieren, wenn Benutzer authentifiziert werden



Nachdem sich der Benutzer authentifiziert hat, gibt der Authentifizierungsserver access_token(Zugriffstoken) und refresh_token(Aktualisierungstoken) zurück. Das Zugriffstoken wird in den Antworttext und das Aktualisierungstoken in das Cookie aufgenommen.



Folgendes müssen Sie zum Einrichten von Cookies zum Speichern von Aktualisierungstoken verwenden:



  • Flag HttpOnly- um zu verhindern, dass JavaScript das Token liest.
  • Ein Flag secure=true, das bewirkt, dass Daten nur über HTTPS übertragen werden.
  • Die Flagge SameSite=strictsollte nach Möglichkeit zum Schutz vor CSRF-Angriffen verwendet werden. Dieser Ansatz kann nur verwendet werden, wenn der Autorisierungsserver zum selben Standort wie das System-Frontend gehört. Ist dies nicht der Fall, muss der Autorisierungsserver CORS-Header im Backend festlegen oder andere Methoden verwenden, um sicherzustellen, dass eine Anforderung mit einem Aktualisierungstoken nur von einer autorisierten Website gestellt werden kann.


Schritt 2: Speichern Sie das Zugriffstoken im Speicher



Das Speichern des Zugriffstokens im Speicher bedeutet, dass das Token im Frontend-Code in eine Variable geschrieben wird. Dies bedeutet natürlich, dass das Token verloren geht, wenn der Benutzer die Registerkarte schließt, auf der die Site geöffnet ist, oder die Seite aktualisiert. Aus diesem Grund haben wir ein Aktualisierungstoken.



Schritt 3: Abrufen eines neuen Zugriffstokens mithilfe des Aktualisierungstokens



Wenn sich herausstellt, dass das Zugriffstoken verloren geht oder ungültig ist, müssen Sie den Endpunkt kontaktieren /refresh_token. In diesem Fall wird das Aktualisierungstoken, das in Schritt 1 im Cookie gespeichert wurde, in die Anforderung aufgenommen. Sie erhalten dann ein neues Zugriffstoken, mit dem Sie API-Anforderungen stellen können.



All dies bedeutet, dass JWTs größer als 4 KB sein können und dass sie im Header platziert werden können Authorization.



Ergebnis



Was wir hier behandelt haben, sollte Ihnen einige grundlegende Informationen zum Speichern von JWTs auf dem Client und zur Verbesserung der Sicherheit Ihres Projekts geben.



Wie speichert man JWT auf dem Client?






All Articles