Могут ли файлы cookie защищать токены от атак XSS?

Я создаю механизм аутентификации JWT (JSON Web Token) для веб-приложения на основе браузера Javascript, работающего с сервером без состояния (без сеансов пользователя!), и я хочу знать раз и навсегда, если использование сохранения моего токена JWT в cookie будет защищать мой токен от атак XSS или если нет защиты, поэтому нет реального преимущества перед использованием локального хранилища браузера в моем приложении Javascript.

Я видел, как этот вопрос задавался и отвечал в SO и во многих блогах, но я никогда не видел ответа, который действительно меня удовлетворяет.


Этот вопрос изначально проводился на том основании, что он запрашивает мнение - и, с учетом моей первоначальной формулировки, справедливо. Поэтому позвольте мне пояснить здесь и сейчас, что я не хочу мнения, основанного на смутных представлениях лени разработчика или тому подобного, о том, что основные правила предназначены для устранения. То, что я хочу, это подтвержденный доказательствами Да/Нет ответа. Или:

  • "Да, файлы cookie могут быть защищены от XSS и CSRF, а вот как" или
  • "Нет, защищая ваши файлы cookie от CSRF, вы всегда открываете их для того же типа атаки XSS, что сделало cookie хорошей идеей в первую очередь"

Итак, я собираюсь повторить этот вопрос, используя некоторые упрощающие основные правила, и заранее укажу отверстия, чтобы вы, эксперты, могли установить меня прямо.

Основные правила

  • Ваше приложение - приложение для браузера javascript - оно может быть в AngularJS, но оно может быть выполнено на заказ. Он взаимодействует с сервером через вызовы REST. Скажем, jQuery $ajax вызывает.

  • Сервер не имеет статуса: управление сеансом отсутствует.

  • Пользователи JWT-приложений в качестве основного токена аутентификации ( "токен доступа" на языке OAuth2) и проверяют их на сервере с помощью секретного ключа подписи

  • Игнорируйте другие важные преимущества файлов cookie: управление браузером, меньше вероятность плохого кодирования и т.д. Для этой битвы я хочу рассмотреть абсолютную безопасность и предположить, что мы можем грамотно закодировать любой механизм.

    /li >
  • Игнорировать другие недостатки файлов cookie, таких как не-браузерные приложения и т.д. Для этой битвы мы имеем дело только с браузером javascript-приложения.

  • Не имеет значения, используете ли вы заголовок или тело запроса для передачи токенов в не-cookie-подходе; и не имеет значения, используете ли вы локальное хранилище и хранилище сеансов - игнорируйте любые различия в безопасности. И да, я знаю, что технически Cookies используют заголовки, игнорируют это.


Вкратце, нас интересует только сравнение маркеров-маркеров браузеров с вашими-javascript-ручками-токенами и сравнительными рисками безопасности XSS и CSRF.


Участники

В красном углу Auth0: локальное хранилище удаляет файлы cookie, потому что XSS легче исправить, чем CSRF

В синем углу Stormpath: Cookies бьет заголовки, потому что на самом деле CSRF легче исправить, чем XSS.

(выдержки из обоих аргументов подробно ниже)

Оружие выбора

XSS и CSRF (мы будем использовать CSRF и XSRF взаимозаменяемо: C, похоже, более популярен в документации, код X)

Здесь мое супер-упрощенное резюме типов атаки:

Предположим, что ваше антивирусное приложение, защищенное JWT, для веб-банкинга и злоумышленник, Evil Corp., хочет отправить вызов AJAX REST, который переводит средства на свой счет, выдавая себя за ваших пользователей.

XSS (межсайтовый скриптинг)

(Как указывает Stormpath, есть много векторов атаки - я выберу один)

Evil Corp покупает права учетной записи github для стильного текстового поля, который вы используете для ввода пароля. Они знают, что ваш сайт банка использует его, поэтому они обновляют его для отправки AJAX-запросов на перевод средств на свой счет при вводе вашего паспорта и нажатии ввода. Ваша система сборки глупо выводит обновление и вводит в эксплуатацию.

CSRF (Подпрограмма запроса на межсайтовый запрос)

Evil Corp знает, что ваш сайт банка использует JWT в файлах cookie для аутентификации транзакций, поэтому они пишут веб-приложение, которое отправляет запросы AJAX для перевода средств на свой счет. Они размещают это на собственном сайте evil.com и заманивают вас туда с помощью электронной почты (фишинг) или каким-либо другим способом, когда вы попадаете на свой банковский сайт на другой вкладке. Браузер отправляет запрос с сайта evil.com, но привносит ваш JWT, потому что он подходит к правильному сайту: банку.

Стандартная защита

Защита от XSS должна быть очень осторожной в отношении кода на вашем сайте, чтобы вы никогда не позволяли браузеру обрабатывать то, что пользователь вводит без его очистки (удаление javascript и html), и что все сторонние библиотеки (Evil text виджет поля) проверяются перед использованием. Как справедливо указывает Штурмпат, это сложно, гранича с невозможным.

Защита от CSRF заключается в использовании формы double-submit-cookie. Это означает, что наш сервер создает маркер (безопасно случайная строка) и отправляет его в наше приложение браузера Javascript в читаемом файле cookie (назовите его "XSRF-TOKEN" по соглашению), и наш Javascript отправляет его обратно в заголовок или тело с каждым запросом.

На самом деле, double-sumbit-cookie - это только один защитный agasint CSRF, но некоторые другие требуют сеансов с поддержкой состояния, и ни один другой (я думаю!) не предлагает лучшей защиты. Безгражданство может быть достигнуто путем помещения маркера в JWT и сравнения его на стороне сервера с тем, который входит в заголовок или тело.

Но реальное качество этой защиты CSRF - это политика того же самого происхождения, что только тот javascript, который наше приложение загрузило из нашего домена, может прочитать этот файл cookie. Поэтому даже если javascript на сайте evilcorp.com может отправлять наши файлы cookie с его запросами, он не может вставлять наш XSRF-TOKEN, потому что он не может его прочитать в первую очередь.

Чтобы действительно упростить CSRF:

  • Атаки CSRF работают, потому что браузер, содержащий cookie, зависит только от адресата запроса.
  • Защита CSRF работает, потому что доступ Javascript к файлу cookie зависит от источника Javascript.

Аргумент auth0

С XSS проще справляться, чем в файлах cookie XSRF, есть эта функция, которая позволяет установить флаг HttpOnly со стороны сервера, чтобы они могли быть доступ на сервере, а не от JavaScript. Это полезно, потому что он защищает содержимое этого файла cookie, доступ к которому осуществляется путем ввода клиентский код (XSS). Поскольку токены хранятся в локальном/сеансе хранилище или файл cookie на стороне клиента, они открыты для атаки XSS получая доступ злоумышленника к токену. Это актуальная проблема, и по этой причине вы должны держать свои токены на низком уровне.

Но если вы подумайте о поверхности атаки на куки, одна из главных - XSRF. Реальность такова, что XSRF является одним из самых непонятых атаки и средний разработчик, возможно, даже не понимают риск, поэтому для множества приложений не существует механизма anti-XSRF. Однако, все понимают, что такое инъекция. Проще говоря, если вы позволите вход на ваш сайт, а затем визуализируйте это, не ускользая от него, вы открыты для XSS. Поэтому, основываясь на нашем опыте, легче защитить против XSS, чем защита от XSRF. Добавляя к этому, анти-XSRF не встроенный в каждую веб-инфраструктуру. С другой стороны, XSS легко предотвратите использование синтаксиса escape, доступного по умолчанию для большинства шаблоны. https://auth0.com/blog/2014/01/27/ten-things-you-should-know-about-tokens-and-cookies#xss-xsrf

Аргумент Stormpath

Stormpath рекомендует хранить JWT в файлах cookie для веб-сайтов из-за дополнительной безопасности, которую они предоставляют, и простота защиты от CSRF с использованием современных веб-фреймворков. Веб-хранилище HTML5 уязвимо для XSS, имеет большую поверхность атаки области и может воздействовать на всех пользователей приложения на успешную атаку. https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

также:

Я вижу много дискуссий, в которых файлы cookie удалены от доступа жетоны. В то время как все мы были сожжены системами, в которых хранится идентификатор сеанса в cookie, и что cookie не защищен и, таким образом, украден. Что отстой, но это не повод для использования жетонов. Его причина избежать небезопасные, не-https файлы cookie. https://stormpath.com/blog/token-auth-spa/

Мой прием

Аргумент Stormpath в пользу файлов cookie довольно убедителен, но есть дыра в нем, что я не вижу их адресации четко:


Защита от двойного подчинения CSRF зависит от того, что мой злоумышленник CSRF не может получить доступ к моему файлу cookie: тот, у которого есть XSRF-TOKEN. Но не такой ли файл cookie так же уязвим в XSS-атаке, как локальное хранилище?


Эксплуатация XSS может запускать javascript в моем домене, поэтому он может читать те же файлы cookie, что и мой javascript. (Браузер не знает, что это не мой Javascript)

Чтобы посмотреть на него с другой стороны: локальное хранилище защищено политикой того же самого происхождения, что и читаемый файл cookie. Если я использую подход Auth0, а злоумышленник XSS знает, как найти мой JWT в локальном хранилище и использовать его. Не может ли тот же самый злоумышленник использовать тот же XSS script, чтобы захватить мой файл cookie XSRF-TOKEN и использовать его?

Обе атаки требуют, чтобы они читали и понимали мое приложение javascript, но это было в их браузере.

И какая разница? Является ли кто-то более безопасным, чем другой, и почему?

Ответ 1


_Abandon все надежды, если вы не можете защитить XSS! _

или

Выберите подход, который подходит вам по другим критериям, потому что обе они одинаково безопасны, одинаково небезопасны.


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

Но в любом случае ваш исходный код является общедоступным (JavaScript в вашем браузере), поэтому для мотивированного хакера нет существенной разницы в усилиях по поиску того, какой токен вытащить из локального хранилища и прочитать файл cookie XSRF-TOKEN. Если Evil Corp может получить некоторый JavaScript, работающий в вашем домене, - то XSS - тогда вы будете hosed.

Критерии, не связанные с безопасностью, которые вы можете рассмотреть по вашему выбору:

  • Файлы cookie удобны, потому что вам не нужно писать код JavaScript для управления токеном - только XSRF.

  • Перенаправление становится немного более автоматическим, если вы хотите его использовать.

  • Локальное хранилище легче адаптировать к приложениям, отличным от браузера, с точки зрения сервера, потому что, если вы пишете, скажем, приложение Android на Java, которое не хочет иметь дело с кукисами, ваш сервер не " t нужно делать какие-либо различия между браузером и браузером, поскольку он не использует файлы cookie.

В любом случае, придумайте свой разум, но будьте осторожны с написанным вами JavaScript и сторонним JavaScript, который вы используете!