В контексте JWT Stormpath написал довольно полезную статью, в которой изложены возможные способы их хранения и (не) преимущества, относящиеся к каждому методу.
В нем также содержится краткий обзор атак XSS и CSRF и способов борьбы с ними.
Я приложил несколько коротких фрагментов статьи ниже, на случай, если их статья будет отключена или их сайт отключится.
Локальное хранилище
Проблемы:
Веб-хранилище (localStorage / sessionStorage) доступно через JavaScript в том же домене. Это означает, что любой JavaScript, работающий на вашем сайте, будет иметь доступ к веб-хранилищу, и из-за этого может быть уязвим к атакам межсайтового скриптинга (XSS). Короче говоря, XSS - это тип уязвимости, когда злоумышленник может внедрить JavaScript, который будет работать на вашей странице. Базовые XSS-атаки пытаются внедрить JavaScript через ввод данных, где злоумышленник ставит предупреждение («Вы взломаны»); в форму, чтобы увидеть, если он запускается браузером и может быть просмотрен другими пользователями.
Предупреждение:
Чтобы предотвратить XSS, общим ответом является экранирование и кодирование всех ненадежных данных. Но это далеко не полная история. В 2015 году современные веб-приложения используют JavaScript, размещенный на CDN или вне инфраструктуры. Современные веб-приложения включают сторонние библиотеки JavaScript для A / B-тестирования, анализа воронки / рынка и рекламы. Мы используем менеджеры пакетов, такие как Bower, чтобы импортировать чужой код в наши приложения.
Что если скомпрометирован только один из используемых вами сценариев? На страницу может быть встроен вредоносный JavaScript, и веб-хранилище будет взломано. Эти типы атак XSS могут получить все веб-хранилища, которые посещают ваш сайт, без их ведома. Вероятно, поэтому многие организации советуют не хранить ничего ценного или доверять какой-либо информации в веб-хранилище. Это включает в себя идентификаторы сессии и токены.
В качестве механизма хранения Web Storage не применяет никаких безопасных стандартов во время передачи. Любой, кто читает и использует веб-хранилище, должен проявить должную осмотрительность, чтобы всегда отправлять JWT по HTTPS, а не по HTTP.
Печенье
Проблемы:
Файлы cookie, используемые с флагом cookie HttpOnly, недоступны через JavaScript и защищены от XSS. Вы также можете установить флажок Безопасный файл cookie, чтобы гарантировать, что файл cookie отправляется только через HTTPS. Это одна из основных причин того, что в прошлом cookie-файлы использовались для хранения токенов или данных сеанса. Современные разработчики не решаются использовать куки, потому что они традиционно требовали, чтобы состояние сохранялось на сервере, что нарушает рекомендации RESTful. Файлы cookie как механизм хранения не требуют сохранения состояния на сервере, если вы сохраняете JWT в файле cookie. Это потому, что JWT инкапсулирует все, что нужно серверу для обслуживания запроса.
Однако файлы cookie уязвимы для атак другого типа: подделка межсайтовых запросов (CSRF). CSRF-атака - это тип атаки, которая происходит, когда вредоносный веб-сайт, электронная почта или блог заставляют веб-браузер пользователя выполнять нежелательные действия на доверенном сайте, на котором пользователь в настоящий момент проходит проверку подлинности. Это эксплойт того, как браузер обрабатывает куки. Файл cookie может быть отправлен только на те домены, на которых он разрешен. По умолчанию это домен, который изначально установил cookie. Файл cookie будет отправлен для запроса независимо от того, находитесь ли вы на galaxies.com или hahagonnahackyou.com.
Предупреждение:
Современные браузеры поддерживают SameSite
флаг , в дополнение к HttpOnly
и Secure
. Целью этого флага является предотвращение передачи cookie в межсайтовых запросах, предотвращая многие виды CSRF-атак.
Для браузеров, которые не поддерживают SameSite
, CSRF можно предотвратить с помощью синхронизированных шаблонов токенов. Это звучит сложно, но все современные веб-фреймворки поддерживают это.
Например, у AngularJS есть решение для проверки того, что файл cookie доступен только вашему домену. Прямо из документов AngularJS:
При выполнении запросов XHR служба $ http считывает токен из файла cookie (по умолчанию XSRF-TOKEN) и устанавливает его в качестве заголовка HTTP (X-XSRF-TOKEN). Поскольку только cookie, который работает в вашем домене, может читать cookie, ваш сервер может быть уверен, что XHR пришел из JavaScript, работающего в вашем домене. Вы можете сделать эту защиту CSRF без сохранения состояния, включив xsrfToken
утверждение JWT:
{
"iss": "http://galaxies.com",
"exp": 1300819380,
"scopes": ["explorer", "solar-harvester", "seller"],
"sub": "tom@andromeda.com",
"xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e"
}
Использование CSRF-защиты вашего веб-фреймворка делает файлы cookie надежными для хранения JWT. CSRF также можно частично предотвратить, проверив заголовок HTTP Referer и Origin в вашем API. Атаки CSRF будут иметь заголовки Referer и Origin, которые не связаны с вашим приложением.
Полный текст статьи можно найти здесь:
https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/
У них также есть полезная статья о том, как наилучшим образом спроектировать и внедрить JWT в отношении структуры самого токена:
https://stormpath.com/blog/jwt-the-right-way/