Где хранить JWT в браузере? Как защитить от CSRF?

Я знаю аутентификацию на основе файлов cookie. Флаг SSL и HttpOnly может применяться для защиты аутентификации на основе файлов cookie от MITM и XSS. Однако для защиты его от CSRF потребуются дополнительные специальные меры. Они немного сложнее. (ссылка)

Недавно я обнаружил, что JSON Web Token (JWT) довольно горячий как решение для аутентификации. Я знаю информацию о кодировании, расшифровке и проверке JWT. Тем не менее, я не понимаю, почему некоторые веб-сайты/руководства не нуждаются в защите CSRF, если используется JWT. Я прочитал довольно много и попытаюсь подытожить проблемы ниже. Я просто хочу, чтобы кто-то мог представить большую картину JWT и прояснить концепции, которые я неправильно понял о JWT.

  • Если JWT хранится в cookie, я думаю, что он такой же, как аутентификация на основе cookie, за исключением того, что серверу не нужно иметь сеансы для проверки cookie/токена. По-прежнему существует риск для CSRF, если не будет применена специальная мера. Разве JWT не хранится в cookie?

  • Если JWT хранится в localStorage/sessionStorage, тогда никакие файлы cookie, поэтому не нужно защищать от CRSF. Вопрос заключается в том, как отправить JWT на сервер. Я нашел здесь, предлагая использовать jQuery для отправки JWT по HTTP-заголовку запросов ajax. Таким образом, только аутентификации ajax могут выполнять аутентификацию?

  • Кроме того, я обнаружил, что еще один blog показывает использование "заголовка авторизации" и "несущей" для отправки JWT. Я не понимаю метод, о котором говорит блог. Может ли кто-нибудь объяснить больше о "заголовке авторизации" и "несущей"? Означает ли это, что JWT передается HTTP-заголовком ВСЕХ запросов? Если да, то как насчет CSRF?

Ответ 1

Тоны JWT популярны, поскольку они используются в качестве формата токена по умолчанию в новых протоколах авторизации и аутентификации, таких как OAuth 2.0 и OpenID Connect.

Когда токен хранится в файле cookie, браузер автоматически отправляет его вместе с каждым запросом в тот же домен, и это все еще уязвимо для атак CSRF.

Проверка подлинности на предъявителя является одной из схем аутентификации, определенных в HTTP. В основном это означает, что YOU вставить маркер (JWT) в HTTP-заголовке авторизации запроса. Браузер NOT сделает это автоматически, поэтому он не подходит для защиты вашего веб-сайта. Поскольку браузер автоматически не добавляет заголовок к вашему запросу, он не уязвим для атаки CSRF, которая зависит от вашей аутентификационной информации, отправляемой автоматически в исходный домен.

Схема несущей часто используется для защиты веб-API (сервисов REST), которые расходуются через вызовы AJAX или от мобильных клиентов.

Ответ 2

Нам нужно сохранить JWT на клиентском компьютере. Если мы сохраним его в LocalStorage/SessionStorage, его можно легко захватить с помощью атаки XSS. Если мы храним его в куки, тогда хакер может использовать его (не читая его) в атаке CSRF и выдавать себя за пользователя и обращаться к нашему API и отправлять запросы на действия или получать информацию от имени пользователя.

Но есть несколько способов защитить JWT в файлах cookie, чтобы они не были легко украдены (но есть все же некоторые продвинутые методы, чтобы украсть их). Но если вы хотите полагаться на LocalStorage/SessionStorage, тогда к нему можно получить доступ с помощью простой атаки XSS.

Итак, чтобы решить проблему CSRF, я использую Double Submit Cookies в своем приложении.

Метод двойной отправки cookie

  • Храните JWT в файле cookie HttpOnly и используйте его в защищенном режиме для передачи по HTTPS.

  • Большинство атак CSRF имеют разные заголовки происхождения или реферера с исходным хостом в своих запросах. Поэтому проверьте, есть ли у вас какой-либо из них в заголовке, они поступают из вашего домена или нет! Если не отклонить их. Если в запросе нет источника и источника ссылок, тогда не стоит беспокоиться. Вы можете положиться на результат результатов проверки заголовка X-XSRF-TOKEN, которые я объясню на следующем шаге.

  • В то время как браузер автоматически предоставит ваши файлы cookie для домена запроса, есть одно полезное ограничение: код JavaScript, который работает на веб-сайте, не может читать файлы cookie других веб-сайтов. Мы можем использовать это для создания нашего решения CSRF. Чтобы предотвратить атаки CSRF, мы должны создать дополнительный Javascript читаемый файл cookie, который называется: XSRF-TOKEN. Этот файл cookie должен быть создан при входе пользователя в систему и должен содержать произвольную строку с недопустимыми значениями. Мы также сохраняем это число в самой JWT как частное требование. Каждый раз, когда приложение JavaScript хочет сделать запрос, ему нужно будет прочитать этот токен и отправить его в пользовательский заголовок HTTP. Поскольку эти операции (чтение файла cookie, настройка заголовка) могут выполняться только в том же домене приложения JavaScript, мы можем знать, что это выполняется реальным пользователем, который использует наше приложение JavaScript.

Angular JS упрощает вашу жизнь

К счастью, я использую Angular JS в нашей платформе, а Angular - это подход к токенам CSRF, что упрощает реализацию. Для каждого запроса, который делает наше приложение Angular на сервере, служба Angular $http будет делать это автоматически:

  • Найдите в текущем домене файл cookie с именем XSRF-TOKEN.
  • Если этот файл cookie найден, он считывает значение и добавляет его в запрос как заголовок X-XSRF-TOKEN.

Таким образом, реализация на стороне клиента выполняется автоматически, автоматически! Нам просто нужно установить cookie с именем XSRF-TOKEN в текущем домене на стороне сервера, и когда наш API получил какой-либо вызов от клиента, он должен проверить заголовок X-XSRF-TOKEN и сравнить его с XSRF-TOKEN в JWT. Если они совпадают, то пользователь реален. В противном случае это кованый запрос, и вы можете его игнорировать. Этот метод вдохновлен методом "Double Submit Cookie".

Внимание!

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

Сохраняете ли вы JWT в localStorage или вы храните свой XSRF-токен в не HttpOnly cookie, оба могут быть легко схвачены XSS. Даже ваш JWT в HttpOnly cookie может быть захвачен расширенной атакой XSS, например метод XST.

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

Подробнее здесь: