Czy JWT powinien być przechowywany w localStorage czy w pliku cookie? [duplikować]

101

W celu zabezpieczenia REST API za pomocą JWT, zgodnie z niektórymi materiałami (takimi jak ten przewodnik i to pytanie ), JWT może być przechowywany w localStorage lub Cookies . Na podstawie mojego zrozumienia:

  • localStorage podlega XSS i generalnie nie zaleca się przechowywania w nim żadnych poufnych informacji.
  • Za pomocą plików cookie możemy zastosować flagę „httpOnly”, która zmniejsza ryzyko XSS. Jeśli jednak mamy odczytać token JWT z plików cookie na zapleczu, wówczas podlegamy CSRF.

Opierając się więc na powyższej przesłance - najlepiej będzie, jeśli będziemy przechowywać JWT w plikach Cookies. Przy każdym żądaniu do serwera token JWT zostanie odczytany z plików Cookies i dodany w nagłówku Authorization za pomocą schematu Bearer. Serwer może następnie zweryfikować token JWT w nagłówku żądania (w przeciwieństwie do odczytywania go z plików cookie).

Czy moje rozumienie jest prawidłowe? Jeśli tak, czy powyższe podejście ma jakiekolwiek obawy dotyczące bezpieczeństwa? A może w pierwszej kolejności możemy po prostu uciec od używania localStorage?

pkid169
źródło
@ lrn2prgrm, ponieważ nie należy używać razem (bezstanowej) JWT i (stanowej) semantyki sesji.
ozanmuyes

Odpowiedzi:

56

Podoba mi się metoda XSRF Double Submit Cookies, o której wspomniano w artykule @ pkid169, ale jest jedna rzecz, której artykuł ci nie mówi. Nadal nie jesteś chroniony przed XSS, ponieważ atakujący może wstrzyknąć skrypt, który odczytuje plik cookie CSRF (który nie jest HttpOnly), a następnie wysyła żądanie do jednego z punktów końcowych interfejsu API za pomocą tego tokenu CSRF z plikiem cookie JWT wysyłanym automatycznie.

Tak więc w rzeczywistości nadal jesteś podatny na XSS, po prostu atakujący nie może ukraść Ci tokena JWT do późniejszego wykorzystania, ale nadal może wysyłać żądania w imieniu użytkowników za pomocą XSS.

Niezależnie od tego, czy przechowujesz swój token JWT w localStorage, czy też przechowujesz token XSRF w pliku cookie nie zawierającym tylko http, oba mogą być łatwo przechwycone przez XSS. Nawet twój JWT w pliku cookie HttpOnly może zostać przechwycony przez zaawansowany atak XSS.

Dlatego oprócz metody Double Submit Cookies, należy zawsze stosować najlepsze praktyki przeciwko XSS, w tym przed zawartością ucieczki. Oznacza to usunięcie każdego wykonywalnego kodu, który spowodowałby, że przeglądarka zrobiłaby coś, czego nie chcesz. Zwykle oznacza to usunięcie tagów // <! [CDATA [i atrybutów HTML, które powodują ocenę JavaScript.

Iman Sedighi
źródło
11
Czy możesz wyjaśnić, w jaki sposób można pobrać token JWT w pliku cookie HttpOnly? Może być używany przez XSRF, jeśli token XSRF jest zagrożony przez XSS, ale czy naprawdę może zostać przechwycony sam?
Jacek Gorgoń
1
Wiem, że to stary post, ale chciałbym zadać kilka pytań ... Czy to oznacza, że ​​dobrze spreparowane skrypty mogą czytać zarówno localStorage, jak i cookie? Jeśli tak, czy można bezpiecznie założyć, że token JWT może zostać skradziony bez względu na to, gdzie przechowujemy go w przeglądarce? Wtedy czuję, że poleganie wyłącznie na JWT jest bardzo ryzykowne.
Hiroki
2
„Nawet Twój token JWT w pliku cookie HttpOnly może zostać przechwycony przez zaawansowany atak XSS”. to fałsz. Edytował oryginalny post, aby to poprawić.
java-addict301
„Nawet Twój token JWT w pliku cookie HttpOnly może zostać przechwycony przez zaawansowany atak XSS”. Mogę sobie wyobrazić, że ktoś przechwytuje plik cookie, wysyłając go na swój własny serwer. W tym celu może użyć funkcji pobierania z odpowiednią wartością flagi referencji. Głównym problemem jest ochrona CORS, ale w pewnych okolicznościach myślę, że jest to możliwe.
bartnikiewi.cz
„Skrypt wstrzykiwania, który odczytuje plik cookie CSRF (który nie jest HttpOnly)” Domyślna implementacja Html.AntiForgeryToken()w ASP.NET MVC używa pliku cookie HttpOnly dla tokenu CSRF. Myślę, że nadal jesteś podatny na niektóre XSS, ale pomyślałem, że warto o tym wspomnieć.
Lovethenakedgun
21

W aktualnym poście ze Stormpath dość dużo rozwinąłem moje punkty i odpowiedziałem na moje pytanie.

TL; DR

Przechowuj token JWT w plikach cookie, a następnie przekazuj token JWT w nagłówku Authorization przy każdym żądaniu, o którym wspomniałem, lub jak sugeruje artykuł, polegaj na zapleczu, aby zapobiec CSRF (np. Używając xsrfTokenw przypadku Angulara).

pkid169
źródło
2
Witam, nie jestem pewien, czy to jest poprawne, ale czy są jakieś szczególne wady używania plików cookie do przechowywania jwt podczas wdrażania CrossOrigin dla kontrolerów, to jest scena, w której moja aplikacja serwera znajduje się w innym miejscu i wywołujemy api z niego w naszej aplikacji klienckiej, która znajduje się powiedzmy w innym mieście? Czy nie dlatego wielu dostawców usług internetowych powstrzymuje się od używania plików cookie?
valik
CrossOrigin nie oznacza fizycznych lokalizacji. Odnosi się do żądań pochodzących z innych domen. W .net core, decydując się na użycie CORS, określasz, które domeny chcesz zezwolić; jakie nagłówki pozwolisz itp.
Brian Allan West
11
  • Nie przechowuj swojego tokena w LocalStorage lub SessionStorage, ponieważ taki token można odczytać z javascript i dlatego jest podatny na atak XSS.
  • Nie przechowuj swojego tokena w Cookie. Cookie (z flagą HttpOnly) to lepsza opcja - jest podatna na XSS, ale jest podatna na atak CSRF

Zamiast tego podczas logowania możesz dostarczyć dwa tokeny: token dostępu i token odświeżania. Token dostępu powinien być przechowywany w pamięci Javascript, a token odświeżania powinien być przechowywany w HttpOnly Cookie. Refresh token służy tylko i wyłącznie do tworzenia nowych tokenów dostępu - nic więcej.

Gdy użytkownik otworzy nową kartę lub odświeży stronę, należy wykonać żądanie utworzenia nowego tokena dostępu, na podstawie tokena odświeżania przechowywanego w Cookie.

Gorąco polecam również przeczytanie tego artykułu: https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/

devstructor
źródło
5
Skąd ta dodatkowa złożoność, skoro token odświeżania można po prostu traktować jako token dostępu? Jak to podejście bardziej bezpieczne podano mi oznaczyć jako token dostępu secure, samesite: strict, http-only?
Uroczy robot
to nie jest bezpieczniejsze
Chris Hawkes
2

Aby zapobiec atakom CSRF, które wykorzystują istniejące pliki cookie, możesz ustawić plik cookie za pomocą SameSitedyrektywy. Ustaw go na laxlub strict.

To wciąż jest wersja robocza i od 2019 roku nie jest w pełni obsługiwana przez wszystkie obecne przeglądarki , ale w zależności od wrażliwości danych i / lub kontroli nad przeglądarkami używanymi przez użytkowników może być realną opcją. Ustawienie dyrektywy na SameSite=laxpozwoli na „nawigację najwyższego poziomu, która używa„ bezpiecznej ”... metody HTTP”.

Ian Hunter
źródło