Почему нельзя хранить важные данные в localStorage и вообще, JWT чем-то опаснее cookie?



@xenon

При использовании JWT, надо его где-то хранить (иначе он теряется, если пользователь обновляет страницу). Удобно было бы хранить в localStorage/sessionStorage, но многие туториалы и статьи отговаривают от этого, мол, к localStorage есть доступ у всех JS скриптов, и если в результате уязвимости (взломан сервер third-party скрипта, уязвимость в своем коде, XSS) взломщик может украсть JWT, и использовать его (украсть сессию). А вот украсть таким образом httpOnly cookie невозможно, и в этом у куки есть преимущество.

Звучит разумно на первый взгляд. Но если подумать — то у меня не складывается. Допустим у нас есть приложение, «личный кабинет», и, например, есть функция deleteDocument(), которая удаляет документ с сервера через fetch/XHR к бэкенду (POST запрос с httpOnly cookie). И в этом нашем приложении есть уязвимость, которая позволяет выполнить JS код. Украсть куку через эту уязвимость нельзя, но ведь это и не нужно? Все что может хотеть сделать взломщик, он может сделать прямо в этом коде, например, вызвать deleteDocument(), и хоть даже и не получит куку, но он нанесет ущерб.

Есть ли какие-то ситуации, когда использование httpOnly сессионной куки нас защищает, а вот использование localStorage и sessionStorage уязвимо?

Примеры «отговариваний» от localstorage:
https://auth0.com/docs/tokens/token-storage#don-t-…
https://developer.okta.com/blog/2017/08/17/why-jwt…


Решения вопроса 0


Ответы на вопрос 4



@zoonman

Важные данные обычно никогда не хранятся на клиенте, они передаются, используются и удаляются.

Есть ли какие-то ситуации, когда использование httpOnly сессионной куки нас защищает, а вот использование localStorage и sessionStorage уязвимо?

Если есть компроментация клиента, то никак не защищает. Единственное место, это где JS вообще в принципе не используется, т.е. клиенты с отключенным JS. Ну это как в рыцарских доспехах ходить по улице. Неудобно, но вроде как защищает от меча. Только с мечом уже давно не ходят, все больше с автоматами.

Теперь про токены. Токены в теории лучше всего держать не в localStorage, а в sessionStorage. Это хранилище переживает перезагрузки страниц и не расшарено между табами. Т.е. при открытии того же самого адреса в новом табе будет созданая новая сессия. Хранилище очищается при закрытии браузера и таба. Но это жутко неудобно, каждый раз логиниться. Поэтому здравая логика говорит об использовании localStorage, хотя если вы совсем отбитый, то можете хранить токен в сессионой куке.

Если вы прочли те статьи внимательно, то можно понять, что преимущества сессионных кук нивелируются неудобством их использования.
JWT Токены предназначены для микросервисной архитектуры. Т.е. у вас есть некоторый центр аутентификации, который выдает вам токен. Токен этот подписан относительно стойкой криптографией и постоянно ротируется.
Этот токен передается другим микросервисам, которые могут его верифицировать через публичные ключи (JWKS).
Т.е. если вы хотите, вы можете строить свои сервисы так, что они доверяют не только вашему центру аутентификации, но и гуглу с амазоном через OpenID. Есть ситуации, например когда вы хотите разрешить доступ к сервису сотрудникам другой компании. Например, когда такая компания огромна (десятки тысяч сотрудников). Они аутенфицируются у себя, а вы проверяете, что токен выпущен сервисом данной компании. Это не так сложно реализовать.
Реализация авторизации лежит на плечах каждого микросервиса и напрямую завязана на бизнес-логику. Как правило это некий внутренний микросервис, который интегрирован c middleware микросервиса.



@pro100chel

Если ты подключишь вредоносный JS и атака будет целевой то уже ничего не спасет. Как ты не пыхти от этого не защититься. Если только не проверять код библиотек, которые подключаешь на сайте. Это на самом деле и не всегда возможно. Если хочешь защититься то не подключай скрипты со сторонних cdn. Скачивай их, проверяй на уязвимости хотя бы поверхностно и смотри на странности (работа с куки из js и т.д.) и потом уже устанавливай скрипт на сайт.

Касаемо защиты от всякого дерьмеца по типу стиллеров, ботнетов и прочего то тут если уверен что нет уязвимостей и ничего не боишься то юзай localstorage.
Если же не нужно на других доменах проводить проверку входа то лучшим решением будет httponly кука и anticsrf токены.

В любых случаях токены должны быть маложивущими (желательно несколько минут).



@yonen93148

Гыыы! localStorage, как я понял, это ВНУТРИ самого браузера. И хотелось бы знать КАК можно туда заглянуть! А вот куки передаются по сети и их можно отловить. Можно и localStorage посмотреть, но сложно. Если ломануть страницу, на которую этот браузер ломится. Но тут вопрос: -Если СЛОМАН СЕРВЕР на хрена лезть в БРАУЗЕР?!?!?! По-моему это туфта со сломом localStorage. Кроме того, при использовании localStorage можно куки НЕ ПОСЫЛАТЬ, а сервер может подкидывать скрипт, который крутанётся на браузере и САМ браузер использует то, что у него есть для сервера в localStorage, а на сервер пошлёт УЖЕ ТОЛЬКО РЕЗУЛЬТАТЫ проверки/использования. Браузер может брать данные сервера, химичить с ними что-то, а потом сравнивать то, что получилось со своим localStorage. Я так и делаю. Назад идёт не то, что есть в localStorage и не то, что я с сервера взял, а результат обработки данных с сервера и localStorage. И как тут увидеть что-то из LocalStorage?!?!?! Куки и то проще перехватить!



@zkrvndm

Если делайте для себя, то вполне безопасно использовать localStorage. Лично мне самому непринципиально, где хранить авторизационные данные. Например, в своём последнем проекте я токены и вовсе в IndexedDB пихал. Даже если браузер пользователя заражён зловредным расширением, это надо еще догадаться токены в indexedDB искать. К тому же, даже если достать токен, то это ничего не даст, так как токен отнюдь не вечный.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *