Следует ли хранить JWT в localStorage или cookie? [дубликат]

101

С целью обеспечения REST API с помощью JWT, по мнению некоторых материалов (как это руководство , и этот вопрос ), то JWT , может храниться в любом LocalStorage или печенье . Исходя из моего понимания:

  • localStorage подвержен XSS и обычно не рекомендуется хранить в нем какую-либо конфиденциальную информацию.
  • С помощью файлов cookie мы можем применить флаг httpOnly, который снижает риск XSS. Однако, если мы хотим прочитать JWT из файлов cookie на бэкэнде, мы подвергаемся CSRF.

Итак, исходя из вышеизложенного, будет лучше, если мы будем хранить JWT в файлах cookie. При каждом запросе к серверу JWT будет считываться из файлов cookie и добавляться в заголовок авторизации с использованием схемы Bearer. Затем сервер может проверить JWT в заголовке запроса (в отличие от чтения его из файлов cookie).

Я правильно понимаю? Если да, есть ли у вышеуказанного подхода какие-либо проблемы с безопасностью? Или на самом деле мы можем просто обойтись без использования localStorage?

pkid169
источник
@ lrn2prgrm, поскольку не следует использовать (без состояния) JWT и (с сохранением состояния) семантику сеанса вместе.
ozanmuyes 05

Ответы:

56

Мне нравится метод двойной отправки файлов cookie XSRF, который упоминается в статье @ pkid169, но есть одна вещь, о которой вам не говорится. Вы по-прежнему не защищены от XSS, потому что злоумышленник может внедрить сценарий, который считывает ваш файл cookie CSRF (который не является HttpOnly), а затем выполнить запрос к одной из ваших конечных точек API, используя этот токен CSRF с автоматически отправляемым файлом cookie JWT.

Таким образом, на самом деле вы все еще уязвимы для XSS, просто злоумышленник не может украсть ваш токен JWT для последующего использования, но он все еще может делать запросы от имени ваших пользователей с помощью XSS.

Независимо от того, храните ли вы свой JWT в localStorage или храните свой XSRF-токен не только в файле cookie http, XSS может легко захватить оба. Даже ваш JWT в файле cookie HttpOnly можно захватить с помощью расширенной XSS-атаки.

Таким образом, в дополнение к методу двойной отправки файлов cookie вы всегда должны следовать лучшим практикам в отношении XSS, включая экранирование содержимого. Это означает удаление любого исполняемого кода, который заставил бы браузер делать что-то, чего вы не хотите. Обычно это означает удаление тегов // <! [CDATA [и атрибутов HTML, которые вызывают оценку JavaScript.

Иман Седиги
источник
11
Не могли бы вы прояснить, как можно получить JWT в файле cookie HttpOnly? Он может использоваться XSRF, если токен XSRF скомпрометирован XSS, но действительно ли он может быть захвачен самим?
Яцек Горгонь
1
Я знаю, что это старый пост, но я хотел бы задать несколько вопросов ... Означает ли это, что хорошо написанные скрипты могут читать как localStorage, так и файлы cookie? Если да, то можно ли предположить, что JWT может быть украден независимо от того, где мы храним его в браузере? Тогда я считаю, что полагаться исключительно на JWT очень рискованно.
Hiroki
2
«Даже ваш JWT в файле cookie HttpOnly может быть захвачен продвинутой атакой XSS». ложно. Отредактировал исходный пост, чтобы исправить это.
java-addict301
«Даже ваш JWT в файле cookie HttpOnly может быть перехвачен расширенной атакой XSS». Я могу представить, что кто-то захватывает cookie, отправляя его на свой сервер. Для этого он может использовать выборку с правильным значением флага учетных данных. Основная проблема здесь - защита CORS, но в некоторых случаях я думаю, что это возможно.
bartnikiewi.cz
«внедрить сценарий, который читает ваш файл cookie CSRF (который не является HttpOnly)» Реализация по умолчанию Html.AntiForgeryToken()в ASP.NET MVC использует файл cookie HttpOnly для маркера CSRF. Я думаю, что вы все еще восприимчивы к определенным XSS, но подумал, что об этом стоит упомянуть.
Lovethenakedgun
21

Своевременный пост от Stormpath в значительной степени развил мои мысли и ответил на мой вопрос.

TL; DR

Сохраните JWT в файлах cookie, а затем либо передайте JWT в заголовке авторизации по каждому запросу, как я уже упоминал, либо, как предлагается в статье, полагайтесь на бэкэнд для предотвращения CSRF (например, использование xsrfTokenв случае Angular).

pkid169
источник
2
Привет, я не уверен, правильно ли это, но есть ли какие-то особые недостатки в использовании файлов cookie для хранения jwt, когда вы реализуете CrossOrigin для своих контроллеров, это сцена, в которой мое серверное приложение находится в другом месте, и мы вызываем api из него в нашем клиентском приложении, которое, скажем, находится в другом городе? Разве не поэтому многие поставщики веб-услуг воздерживаются от использования файлов cookie?
valik
CrossOrigin не означает физическое местоположение. Это относится к запросам, поступающим из других доменов. В ядре .net, когда вы решаете использовать CORS, вы указываете, какие домены вы собираетесь разрешить; какие заголовки вы разрешите и т. д.
Брайан Аллан Уэст,
11
  • Не храните свой токен в LocalStorage или SessionStorage, потому что такой токен может быть прочитан из javascript и, следовательно, уязвим для XSS-атаки.
  • Не храните свой токен в Cookie. Cookie (с флагом HttpOnly) - лучший вариант - он подвержен XSS-атакам, но уязвим для CSRF-атак.

Вместо этого при входе в систему вы можете доставить два токена: токен доступа и токен обновления. Токен доступа должен храниться в памяти Javascript, а токен обновления должен храниться в HttpOnly Cookie. Токен обновления используется только и только для создания новых токенов доступа - не более того.

Когда пользователь открывает новую вкладку или при обновлении сайта, вам необходимо выполнить запрос на создание нового токена доступа на основе токена обновления, который хранится в Cookie.

Также настоятельно рекомендую прочитать эту статью: https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/

devstructor
источник
5
Зачем нужна дополнительная сложность, если вы можете просто рассматривать токен обновления как токен доступа? Как этот подход более безопасный дали отмечает мой маркер доступа , как secure, samesite: strict, http-only?
Очаровательный робот
это не более безопасно
Крис Хоукс
2

Чтобы предотвратить атаки CSRF, использующие существующие файлы cookie, вы можете установить свой файл cookie с помощью SameSiteдирективы. Установите его на laxили strict.

Это все еще черновик и по состоянию на 2019 год не полностью поддерживается всеми текущими браузерами , но в зависимости от конфиденциальности ваших данных и / или вашего контроля над браузерами, которые используют ваши пользователи, это может быть жизнеспособным вариантом. Установка директивы с SameSite=laxразрешит «навигацию верхнего уровня, использующую« безопасный »... HTTP-метод».

Ян Хантер
источник