Нам нужно хранить JWT на клиентском компьютере. Если мы сохраним его в LocalStorage / SessionStorage, то он может быть легко захвачен атакой XSS. Если мы храним его в cookie-файлах, то хакер может использовать его (без чтения) в CSRF-атаке, выдавать себя за пользователя, связываться с нашим API и отправлять запросы на выполнение действий или получать информацию от имени пользователя.
Но есть несколько способов обезопасить JWT в файлах cookie, чтобы их нельзя было легко украсть (но есть еще несколько продвинутых методов их кражи). Но если вы хотите положиться на LocalStorage / SessionStorage, то к нему можно получить доступ с помощью простой атаки XSS.
Поэтому для решения проблемы CSRF я использую файлы cookie с двойной передачей в своем приложении.
Метод двойного представления файлов cookie
Сохраните JWT в файле cookie HttpOnly и используйте его в безопасном режиме для передачи по HTTPS.
Большинство атак CSRF имеют различный источник или заголовок реферера с вашим исходным хостом в их запросах. Так что проверьте, есть ли у вас какие-либо из них в шапке, они приходят с вашего домена или нет! Если не отвергнуть их. Если в запросе нет ни источника, ни реферера, тогда не стоит беспокоиться. Вы можете положиться на результаты проверки заголовка X-XSRF-TOKEN, которые я объясню на следующем шаге.
Хотя браузер будет автоматически предоставлять ваши файлы cookie для домена запроса, есть одно полезное ограничение: код JavaScript, который выполняется на веб-сайте, не может читать файлы cookie других веб-сайтов. Мы можем использовать это для создания нашего решения CSRF. Чтобы предотвратить CSRF-атаки, мы должны создать дополнительный читаемый Javascript файл cookie, который называется: XSRF-TOKEN. Этот файл cookie должен быть создан, когда пользователь вошел в систему, и должен содержать случайную неуловимую строку. Мы также сохраняем этот номер в самом JWT как частную претензию. Каждый раз, когда приложение JavaScript хочет сделать запрос, ему нужно будет прочитать этот токен и отправить его в пользовательском HTTP-заголовке. Поскольку эти операции (чтение файла cookie, установка заголовка) могут выполняться только в том же домене приложения JavaScript,
Angular JS делает вашу жизнь проще
К счастью, я использую Angular JS в нашей платформе, а Angular упаковывает подход токена CSRF, делая его проще для реализации. Для каждого запроса, который наше приложение Angular отправляет на сервер, $http
служба Angular будет выполнять следующие действия автоматически:
- Найдите файл 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 в файле cookie HttpOnly может быть захвачен расширенной атакой XSS, такой как метод XST .
Таким образом, в дополнение к методу двойной отправки файлов cookie, вы всегда должны следовать передовым методам работы с XSS, включая экранирование содержимого. Это означает удаление любого исполняемого кода, который заставил бы браузер делать то, чего вы не хотите. Как правило, это означает удаление // <![CDATA[
тегов и атрибутов HTML, которые вызывают оценку JavaScript.
Узнайте больше здесь: