Я пытаюсь понять всю проблему с CSRF и соответствующие способы ее предотвращения. (Ресурсы, которые я прочитал, понимаю и согласен с:. OWASP CSRF Prevention CHeat Sheet, Questions about CSRF)Почему распространено помещать токены CSRF в файлы cookie?
Как я понимаю, уязвимость вокруг CSRF вводится в предположении, что (с точки Вебсервер зрения) действительный куки сессии в входящий HTTP-запрос отражает пожелания аутентифицированного пользователя. Но все файлы cookie для домена происхождения магически привязаны к запросу браузера, поэтому на самом деле весь сервер может вывести из присутствия допустимого сеансового файла cookie в запросе, что запрос поступает из браузера, который имеет аутентифицированный сеанс; он не может больше предположить что-либо о код, работающий в этом браузере, или он действительно отражает пожелания пользователей. Способ предотвращения этого состоит в том, чтобы включить в запрос дополнительную аутентификационную информацию («токен CSRF»), переносимую некоторыми средствами, отличными от автоматической обработки файлов cookie браузера. В то же время cookie сеанса аутентифицирует пользователя/браузер, а токен CSRF аутентифицирует код, запущенный в браузере.
Итак, если вы используете cookie сеанса для аутентификации пользователей вашего веб-приложения, вы также должны добавить маркер CSRF для каждого ответа и потребовать соответствующий токен CSRF в каждом (мутирующем) запросе. Затем токен CSRF выполняет обратную пересылку с сервера на браузер обратно на сервер, доказывая серверу, что страница, на которой выполняется запрос, сгенерирована (сгенерирована, даже) на этом сервере.
На мой вопрос, касающийся конкретного метода транспорта, используемого для этого токена CSRF в этом обратном направлении.
кажется распространенным (например, в AngularJS, Django, Rails) послать маркер CSRF от сервера к клиенту, как куки (т.е. в заголовке Set-Cookie), а затем Javascript в клиенте царапать его из cookie и прикрепить его как отдельный заголовок XSRF-TOKEN для отправки на сервер.
(Альтернативный метод является тем, который рекомендуется, например, Express, где токен CSRF, сгенерированный сервером, включен в тело ответа через расширение шаблона на стороне сервера, прикрепленное непосредственно к коду/разметке, которое будет возвращать его обратно сервер, например, как скрытый ввод формы. Этот пример представляет собой более простой способ работы с текстом, но будет обобщать его на более высокий JS-клиент.)
Почему так часто используется Set- Печенье как транспортный поток для токена CSRF/почему это хорошая идея? Я полагаю, авторы всех этих концепций тщательно изучили свои варианты и не ошибались. Но на первый взгляд использование файлов cookie для работы над тем, что по существу является ограничением дизайна для файлов cookie, кажется глупым. Фактически, если вы использовали куки-файлы в качестве транспорта в оба конца (Set-Cookie: заголовок вниз по течению для сервера, чтобы сообщить браузеру токен CSRF, а Cookie: заголовок вверх по течению для браузера, чтобы вернуть его на сервер), вы повторно введете уязвимость, которую вы пытаются исправить.
Я понимаю, что фреймворки выше не используют файлы cookie для всего обратного перехода для токена CSRF; они используют Set-Cookie downstream, затем что-то еще (например, заголовок X-CSRF-Token) вверх по течению, и это закрывает уязвимость. Но даже использование Set-Cookie в качестве нисходящего транспорта потенциально обманчиво и опасно; браузер теперь присоединяет токен CSRF к каждому запросу, включая настоящие вредоносные запросы XSRF; в лучшем случае это делает запрос больше, чем он должен быть, и в худшем случае какой-то здравомыслящий, но ошибочный фрагмент кода сервера действительно может попытаться его использовать, что было бы очень плохо. Кроме того, поскольку фактический предполагаемый получатель токена CSRF является клиентским Javascript, это означает, что этот файл cookie не может быть защищен только с помощью http-only. Поэтому отправка токена CSRF ниже по течению в заголовке Set-Cookie кажется мне довольно субоптимальным.
Спасибо за подробный ответ. Хороший вариант для файлов cookie, оставшихся действительными за всю жизнь начальной загрузки страницы, для приложений, которые не являются одностраничными. – metamatt
Я не уверен, что я понимаю, как «запрос AJAX сделан для получения токена CSRF» (шаг 4 в разделах «пользовательский заголовок: нисходящий поток») можно сделать безопасно; поскольку это отдельный запрос, сервер не знает, от кого он происходит; как он знает, что можно разглашать токен CSRF? Мне кажется, что если вы не можете получить токен из начальной загрузки страницы, вы потеряете (что, к сожалению, делает пользовательский ответный ответный заголовок нестартером). – metamatt
Это было бы сделано так, чтобы одна и та же политика происхождения защищала ответ от чтения другим доменом (например, AJAX POST). – SilverlightFox