Нужно ли использовать защиту CSRF, если приложение использует аутентификацию без сохранения состояния (используя что-то вроде HMAC)?
Пример:
У нас есть одно приложение страницы ( в противном случае мы должны добавить маркер на каждой ссылке:
<a href="...?token=xyz">...</a>
.Пользователь аутентифицируется с помощью
POST /auth
. При успешной аутентификации сервер вернет некоторый токен.Токен будет храниться через JavaScript в некоторой переменной внутри одностраничного приложения.
Этот токен будет использоваться для доступа к URL с ограниченным доступом, например
/admin
.Токен всегда будет передаваться внутри заголовков HTTP.
НЕТ Http-сессии и НЕТ файлов cookie.
Насколько я понимаю, не должно (?!) быть возможности использовать межсайтовые атаки, потому что браузер не будет хранить токен, и, следовательно, он не может автоматически отправить его на сервер (что произойдет при использовании файлов cookie / сессия).
Я что-то упускаю?
Ответы:
Я нашел информацию о CSRF + без использования файлов cookie для аутентификации:
https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/
«поскольку вы не полагаетесь на файлы cookie, вам не нужно защищаться от межсайтовых запросов»
http://angular-tips.com/blog/2014/05/json-web-tokens-introduction/
"Если мы пойдем по пути файлов cookie, вам действительно нужно будет выполнить CSRF, чтобы избежать межсайтовых запросов. Это то, что мы можем забудьте при использовании JWT, как вы увидите ".
(JWT = Json Web Token, аутентификация на основе токенов для приложений без сохранения состояния)
http://www.jamesward.com/2013/05/13/securing-single-page-apps-and-rest-services
«Самый простой способ выполнить аутентификацию, не рискуя уязвимостью CSRF, - просто избегать использования файлов cookie для идентификации пользователя. "
http://sitr.us/2011/08/26/cookies-are-bad-for-you.html
«Самая большая проблема с CSRF заключается в том, что файлы cookie не обеспечивают абсолютно никакой защиты от этого типа атак. Если вы используете аутентификацию файлов cookie вы также должны принять дополнительные меры для защиты от CSRF. Самая основная мера предосторожности, которую вы можете предпринять, - убедиться, что ваше приложение никогда не выполняет никаких побочных эффектов в ответ на запросы GET ".
Есть еще много страниц, на которых говорится, что вам не нужна защита CSRF, если вы не используете файлы cookie для аутентификации. Конечно, вы все еще можете использовать файлы cookie для всего остального, но не храните в них что-либо подобное
session_id
.Если вам нужно запомнить пользователя, есть 2 варианта:
localStorage
: Хранилище ключей и значений в браузере. Сохраненные данные будут доступны даже после того, как пользователь закроет окно браузера. Данные недоступны для других веб-сайтов, потому что каждый сайт получает собственное хранилище.sessionStorage
: Также в хранилище данных браузера. Разница в том, что данные удаляются, когда пользователь закрывает окно браузера. Но это все равно полезно, если ваше веб-приложение состоит из нескольких страниц. Итак, вы можете сделать следующее:sessionStorage
sessionStorage
sessionStorage
либо подождать, пока пользователь закроет окно браузера, что очистит все сохраненные данные.(для обоих посмотрите здесь: http://www.w3schools.com/html/html5_webstorage.asp )
Существуют ли официальные стандарты аутентификации токенов?
JWT (Json Web Token): я думаю, что это все еще черновик, но он уже используется многими людьми, и концепция выглядит простой и надежной. (IETF: http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25 )
Существуют также библиотеки для множества доступных фреймворков. Просто погуглите!
источник
http://.../someRestResource?method=POST
. Таким образом, это в основномGET
запрос, но серверное приложение интерпретирует его какPOST
запрос, поскольку оно было настроено на использованиеmethod
параметра вместо HTTP-заголовка....
Что касается обычных веб-браузеров, они применяют политику одного и того же происхождения и будут выполнятьGET
запросы только к сторонним серверам. Хотя можно было бы выполнятьPOST
запросы, если веб-браузер не применяет эти веб-стандарты (ошибка, вредоносное ПО).Server Side App
: По-прежнему невозможно отправить тело запроса, потому что обычные браузеры не позволяют этого. Однако, если серверное приложение позволяетmethod=POST
, оно также может позволитьbody={someJson}
переопределить тело запроса по умолчанию. Это действительно плохой дизайн API и крайне рискованный. Хотя, если ваше серверное приложение позволяет,http://...?method=POST&body={someJson}
вам действительно стоит задуматься о том, что вы там делали, зачем и нужно ли это вообще. (Я бы сказал, что в 99,9999% случаев в этом нет необходимости). Кроме того, таким образом браузеры могут отправлять только несколько килобайт.TL; DR
JWT, если он используется без файлов cookie, устраняет необходимость в токене CSRF - НО! сохраняя JWT в session / localStorage, вы раскрываете свой JWT и личность пользователя, если ваш сайт имеет XSS-уязвимость (довольно часто). Лучше добавить
csrfToken
ключ к JWT и сохранить JWT в файле cookie с установленными атрибутамиsecure
иhttp-only
.Прочтите эту статью с хорошим описанием для получения дополнительной информации https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage
Таким образом, вам нужно будет сохранить csrfToken в localStorage / sessionStorage, а также в самом JWT (который хранится в защищенном cookie только для http). Затем для защиты csrf убедитесь, что токен csrf в JWT совпадает с отправленным заголовком csrf-token.
источник