SPA (одностраничные приложения), которые широко используют Javascript, часто нуждаются в вызове интерфейсов прикладного программирования (API), чтобы предлагать услуги пользователю. Следовательно, эти приложения должны получить доступ к этим API, т.е. авторизоваться. Этого можно добиться несколькими способами. Современные стандарты, такие как OAuth2, определяют различные потоки, показывающие, как аутентифицированные пользователи (или приложения, действующие от их имени) должны получать токены или учетные данные, которые затем могут использоваться при вызове API-интерфейсов, чтобы подтвердить, что они имеют право вызывать их.

Это означает, что SPA, действующие от имени этих пользователей, должны каким-то образом хранить эти токены, будь то токены доступа, обновления или идентификаторы. Часто рекомендуются такие места, как локальное хранилище Javascript или хранилище сеансов.

Атаки

XSS

Однако эти места уязвимы для атак XSS (межсайтовый скриптинг).

XSS обычно сводится к внедрению вредоносного кода javascript, например. в одной из зависимостей SPA. При выполнении браузером пользователя SPA запускает внедренный код, который может попытаться прочитать локальное содержимое браузера и содержимое хранилища сеанса и отправить его в одну из удаленных баз данных хакера. Если токены / учетные данные сохраняются в этих местах, безопасность оказывается под угрозой, поскольку теперь хакер может выдавать себя за пользователя до тех пор, пока токены / учетные данные действительны или обновляются.

Врагами XSS являются файлы cookie HttpOnly Secure. Обернув токен / учетные данные в один из них, Javascript больше не сможет получить доступ к их содержимому, и браузер будет передавать эти файлы cookie только с обращениями к домену / адресу, который их установил.

CSRF

Однако упаковка токенов / учетных данных в файлы cookie открывает уязвимость для атак CSRF (подделка межсайтовых запросов). На что способен этот новый зверь, лучше всего объяснить следующий очень популярный сценарий:

«На одной вкладке своего браузера пользователь входит в систему со своим банковским счетом SPA, который вернул браузеру HttpOnly Secure Cookie. При каждом запросе, который пользователь делает в свой банк, файл cookie будет передаваться браузером в API, поддерживающий SPA банка, чтобы доказать, что он имеет право совершать такие вызовы.

Тем временем пользователь открывает другую вкладку на вредоносном веб-сайте, предлагая ему щелкнуть видео с котенком, застрявшим в холодильнике. Нажав на видео, злонамеренный веб-сайт отправит запрос в банк пользователя с просьбой перевести все его сбережения на счет хакера. Браузер, увидев, что место назначения запроса соответствует файлу cookie HttpOnly Secure, выданному пользователю при входе в банк, с радостью передаст этот файл cookie. Банковский API развернет файл cookie, заметит, что токен / учетные данные являются действительными, и выполнит перевод денег.

Хакер успешно совершил озорство и теперь может воспользоваться планом досрочного выхода на пенсию ».

Чтобы сделать CSRF-атаки недействительными, обычное решение - заставить SPA передавать токены / учетные данные (то есть с помощью Javascript) в заголовке или другом приемлемом месте запросов к API.

Дилемма

Итак, в двух словах, мы сталкиваемся со следующей дилеммой:

  • Токены / учетные данные, заключенные в файлы cookie HttpOnly Secure, невосприимчивы к XSS, но уязвимы для CSRF
  • Токены / учетные данные, обрабатываемые Javascript и передаваемые в заголовки запросов и т.п., невосприимчивы к CSRF, но уязвимы для XSS.

Лучшее из обоих миров

Чтобы быть устойчивыми как к атакам XSS, так и к CSRF, наиболее распространенная стратегия смягчения последствий примерно соответствует следующим принципам:

  • Добавьте заголовок со случайно сгенерированной строкой (часто называемой токеном CSRF или состоянием в терминах OAuth2)
  • Добавьте ту же случайно сгенерированную строку к токену / учетным данным (проще всего сделать в качестве дополнительного утверждения при использовании JWT, т.е. Json Web Tokens)
  • Оберните токены / учетные данные в HttpOnly Secure Cookie
  • Убедитесь, что API проверяет совпадение случайно сгенерированной строки, содержащейся в заголовке и файле cookie.

→ XSS не будет работать из-за HttpOnly Cookie

→ CSRF не будет работать, потому что злоумышленник не знает, какую случайную строку отправить в заголовке вместе с HttpOnly Secure Cookie

Остающиеся проблемы

Причастность к взлому

По-прежнему можно столкнуться со сценарием, когда злоумышленник получает токен CSRF через XSS-атаку и передает его скрытому запросу на вредоносном веб-сайте злоумышленника, заставляя браузер передавать HttpOnly Secure Cookie для запроса.

Этот сценарий, хотя и возможен, гораздо менее вероятен на практике, поскольку эта атака является гораздо более целенаправленной и тщательно спроектированной.

Неявный поток OAuth2

Возможно, большее беспокойство вызывает неявный поток, определенный стандартом OAuth2.

Этот поток специально нацелен на SPA и предписывает разработчикам серверов авторизации возвращать токены непосредственно в SPA, что делает их уязвимыми для XSS-атак.

Эту модель хвалят уже несколько лет, и только в 2018 году ее начали пересматривать для устранения этой уязвимости.

Проблема в том, что у большинства предприятий нет ни времени, ни ресурсов для создания и обслуживания серверов аутентификации и авторизации. К счастью, на помощь приходят поставщики AaaS (аутентификация как услуга), такие как Auth0, AWS, Google и т. Д., На которых компании сильно полагались в последние годы.

К сожалению, эти провайдеры не в курсе последних реформ стандарта OAuth и не обязательно строго им следуют. И, AFAIK, этот поток не был пересмотрен основными разработчиками AaaS в середине 2019 года. Более того, разработчики AaaS контролируют, как токены отправляются в приложения. Таким образом, предприятия, использующие AaaS, не могут изменить поток для возврата как токенов CSRF, так и файлов cookie HttpOnly Secure, упакованных в токены.

Чтобы глубже разобраться в чуме неявного потока OAuth2, я настоятельно рекомендую заинтересованным читателям прочитать следующий пост: https://auth0.com/blog/oauth2-implicit-grant-and-spa/ Витторио Берточчи, главный архитектор одного из основных провайдеров AaaS. Сообщение подробно рассматривает путь OAuth2 и демонстрирует отсутствие в настоящее время эффективного решения для безопасного использования неявного потока.

Автор Танги Наетс
Инженер по машинному обучению Radix.ai