csrf token что это такое
Атака CSRF
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Нельзя говорить про AJAX и не упомянуть про важнейшую деталь его реализации – защиту от CSRF-атак.
CSRF (Cross-Site Request Forgery, также XSRF) – опаснейшая атака, которая приводит к тому, что хакер может выполнить на неподготовленном сайте массу различных действий от имени других, зарегистрированных посетителей.
Какие это действия – отправка ли сообщений, перевод денег со счёта на счёт или смена паролей – зависят от сайта, но в любом случае эта атака входит в образовательный минимум веб-разработчика.
Злая форма
«Классический» сценарий атаки таков:
Вася попал на «злую страницу», например хакер пригласил его сделать это письмом или как-то иначе.
На злой странице находится форма такого вида:
Сайт mail.com проверяет куки, видит, что посетитель авторизован и обрабатывает форму. В данном примере форма предполагает посылку сообщения.
Итог атаки – Вася, зайдя на злую страницу, ненароком отправил письмо от своего имени. Содержимое письма сформировано хакером.
Защита
В примере выше атака использовала слабое звено авторизации.
Куки позволяют сайту mail.com проверить, что пришёл именно Вася, но ничего не говорят про данные, которые он отправляет.
Иначе говоря, куки не гарантируют, что форму создал именно Вася. Они только удостоверяют личность, но не данные.
Типичный способ защиты сайтов – это «секретный ключ» ( secret ), специальное значение, которое генерируется случайным образом при авторизации и сохраняется в сессии посетителя. Его знает только сервер, посетителю мы его даже не будем показывать.
Разумеется, для разных посетителей secret будет разным.
Формула вычисления токена:
Далее, токен добавляется в качестве скрытого поля к каждой форме, генерируемой на сервере.
Такой токен также называют «подписью» формы, которая удостоверяет, что форма сгенерирована именно на сервере.
Эта подпись говорит о том, что автор формы – сервер, но ничего не гарантирует относительно её содержания.
Есть ситуации, когда мы хотим быть уверены, что некоторые из полей формы посетитель не изменил самовольно. Тогда мы можем включить в MD5 для формулы токена эти поля, например:
Токен и AJAX
Теперь перейдём к AJAX-запросам.
Что если посылка сообщений в нашем интерфейсе реализуется через XMLHttpRequest?
Как и в случае с формой, мы должны «подписать» запрос токеном, чтобы гарантировать, что его содержимое прислано на сервер именно интерфейсом сайта, а не «злой страницей».
Здесь возможны варианты, самый простой – это дополнительная кука.
Код, осуществляющий XMLHttpRequest, получает куку и ставит заголовок X-CSRF-TOKEN с ней:
Сервер проверяет, есть ли заголовок и содержит ли он правильный токен.
Защита действует потому, что прочитать куку может только JavaScript с того же домена. «Злая страница» не сможет «переложить» куку в заголовок.
Если нужно сделать не XMLHttpRequest, а, к примеру, динамически сгенерировать форму из JavaScript – она также подписывается аналогичным образом, скрытое поле или дополнительный URL-параметр генерируется по куке.
Итого
CSRF-атака – это когда «злая страница» отправляет форму или запрос на сайт, где посетитель, предположительно, залогинен.
Если сайт проверяет только куки, то он такую форму принимает. А делать это не следует, так как её сгенерировал злой хакер.
Для подписи XMLHttpRequest токен дополнительно записывается в куку. Тогда JavaScript с домена mail.com сможет прочитать её и добавить в заголовок, а сервер – проверить, что заголовок есть и содержит корректный токен.
Динамически сгенерированные формы подписываются аналогично: токен из куки добавляется как URL-параметр или дополнительное поле.
CSRF-токен
В этой статье рассмотрим, что такое Сross-Site Request Forgery и как включить в Spring Boot приложение CSRF-токен — защиту от этого мошенничества. Назвать этот токен можно было бы «анти-CSRF-токен».
Same Origin Policy и CSRF (cross-site request forgery)
Обычно запросы, сделанные в браузере с одного домена на другой, не проходят, поскольку браузер придерживается Same Origin Policy. Это политика безопасности, защищающая одни сайты от других.
Например, пусть пользователь случайно заходит на домен evil.com (мошеннический сайт) и щелкает там яркую кнопку, которая выполняет либо PUT-запрос, либо DELETE-запрос на bank.com. И так случайно получилось, что этот пользователь зарегистрирован на bank.com и в браузере хранятся куки к нему. Благодаря политике безопасности браузера, ничего плохого не случится. Потому что браузер сначала вышлет так называемый «preflight», то есть предварительный OPTIONS-запрос на bank.com с заголовком
и затем отправит за ним настоящий PUT/DELETE-запрос, но только в том случае, если в ответе пришло разрешение на отправку запросов от evil.com. В противном случае в метод PUT/DELETE банковского сайта мы даже не попадем.
Но есть запросы, которые отправляются сразу, без предварительного запроса, так называемые simple requests. Это GET, HEAD, POST с определенным Content-Type. В частности, POST-запросы с формы. Такой запрос сразу идет в контроллер. А учитывая, что куки браузер отправляет автоматически, запрос попадет в защищенный контроллер и выполнит действие на банковском сайте. Хотя ответ получить и распарсить нельзя, действие будет выполнено.
Ниже рассмотрим, как это происходит. В примере одно приложение на одном домене делает POST-запрос на другой домен, где работает второе приложение. Рассмотрим, как защититься от таких запросов с помощью CSRF-токена.
Пример жульничества
Создадим два приложения на Spring Boot:
Поскольку в примере мы будем делать запрос на «другой домен», пропишем для localhost:8080 новое имя в файле hosts:
А именно, добавим в файл hosts строку:
Теперь к приложению-мишени будем обращаться по адресу http://bank-server:8080/..вместо http://localhost:8080..
Приложение-мишень
Итак, пусть в нашем приложении есть контроллер и форма, с которой что-то добавляется:
Добавление
Форма на Thymeleaf выглядит так:
При этом адрес http://bank-server:8080/add защищен, доступ к нему возможен только благодаря куки JSESSIONID после входа с помощью формы логина.
В приложении задан единственный in-memory пользователь с именем user и паролем user:
Выше прописано, что все запросы доступны только аутентифицированным пользователям (в том числе наша форма — ее получение по адресу /add методом GET и отправка методом POST). Форма находится в шаблоне add.html
Проверку CSRF-токена мы отключили выше отдельной строкой:
Это сделано для того, чтобы продемонстрировать атаку с помощью второго приложения ниже. А затем включить CSRF-токен обратно. (По умолчанию он и так включен, просто нужно не забывать добавлять его и на форму, что будет в показано самом конце).
Мошенническое приложение
Второе приложение совсем простое, оно состоит из одного view с кнопкой атаки POST (полный код тут):
Сайт жуликов
Кнопка отправляет форму со скрытыми полями: и text=«document». Если в браузере мы залогинены в приложении http://bank-server:8080 и откроем мошеннический сайт localhost:8081 с вышеприведенной кнопкой и щелкнем ее, то сохраненный куки JSESSIONID отправляется тоже, и мы попадаем в защищенный метод add() контроллера DocumentController банковского сайта. Документ добавляется.
Защита с помощью CSRF-токена
Чтобы защититься от таких запросов, нужно включить CSRF-токен, то есть убрать строку отключения, которую мы добавили выше:
Теперь когда пользователь логинится на сайт http://bank-server:8080, ему выделяется специальный CSRF-токен. Он хранится в сессии и должен отправляться как скрытое поле со всех форм (также он должен прилагаться в XMLHttpRequest-запросах PUT, DELETE, POST — это для JavaScript). Выше мы показали только одну атаку, но при определенных настройках Spring MVC в определенных браузерах возможны и более сложные атаки. И хотя браузеры становятся все более безопасными, как и сам Spring MVC, все равно Spring Security имеет вот такое требование и для PUT, и для DELETE-запросов, хотя для них существуют «preflight» запросы от браузера. Но эти настройки CSRF-токена можно и поменять — убрать некоторые методы или некоторые url — сделать так, чтобы для них не требовался токен.
Итак, токен в POST-запросах сейчас требуется. Если оставить все как есть, то наше собственное банковское приложение не заработает — при попытке отправить форму получим 403. Надо сделать так, чтобы выданный CSRF-токен отправлялся. Для этого добавим его как скрытое поле на форму в наш Thymeleaf-шаблон:
Все, теперь и наше приложение работает, и с чужого сайта форму отправить нельзя, потому что мошенники не знают CSRF-токен. В отличие от JSESSIONID, он не хранится в куки браузера и не отправляется автоматически при запросах на банковский сайт.
Итоги
Исходный код обоих приложений есть на GitHub.
Как защитить свой сайт с помощью Anti-CSRF токенов
Токены Anti-CSRF (или просто токены CSRF) — это уникальные значения, используемые в веб-приложениях для предотвращения атак с подделкой межсайтовых запросов (CSRF / XSRF). CSRF-атаки — это атаки на стороне клиента, которые могут использоваться для перенаправления пользователей на вредоносный веб-сайт, кражи конфиденциальной информации или выполнения других действий в рамках сеанса пользователя. В этой статье рассказано, как использовать токены CSRF для защиты пользователей от атак CSRF и их последствий.
Основы Anti-CSRF токенов
Основной принцип, лежащий в основе токенов anti-CSRF (также известных как шаблоны токенов синхронизатора), заключается в том, чтобы предоставить браузеру пользователя уникальную информацию (токен) и проверить, отправляет ли веб-браузер ее обратно. Токен должен быть уникальным и его невозможно угадать третьим лицам. Приложение не должно работать, если оно не проверит эту информацию. Таким образом, только исходный пользователь может отправлять запросы в аутентифицированном сеансе.
Допустим, вы запускаете веб-приложение социальной сети на сайте www.example.com. Чтобы опубликовать сообщение в своем профиле, пользователь заполняет HTML-форму и нажимает кнопку «Отправить».
Это заставляет веб-браузер отправлять POST запрос:
Если пользователь вошел в систему и злоумышленник знает синтаксис этого запроса, злоумышленник может использовать CSRF-атаку для публикации рекламы в профиле пользователя:
В результате веб-браузер отправляет следующий POST запрос:
Если ваш сайт использует простой токен anti-CSRF, веб-сервер устанавливает этот токен в cookie сеанса вашего веб-браузера сразу после входа в систему. Все отправленные формы через скрытое поле (hidden field), будут содержать этот токен. Таким образом это полностью устраняет уязвимость CSRF.
Затем сервер проверит, содержит ли каждый POST запрос требуемый токен:
Если злоумышленник попытается выполнить подделку межсайтового запроса с помощью вредоносного сайта, он не узнает текущий токен, установленный в cookie. Ваш сервер не станет обрабатывать запрос без этого токена, поэтому атака не удастся.
Как генерировать и проверять токены
Когда вы создаете и позже проверяете свой токен, следуйте этим принципам, чтобы убедиться, что ваш anti-CSRF токен не может быть угадан или использован иным образом:
Например, в PHP вы можете сгенерировать токен следующим образом:
И проверьте токен следующим образом:
Anti-CSRF защита для форм
Описанный выше токен анти-CSRF устанавливается при входе в систему в файле cookie сеанса пользователя, а затем проверяется каждой формой. В большинстве случаев этой защиты достаточно. Однако некоторые сайты предпочитают использовать более безопасный подход. Чтобы достичь хорошего компромисса между безопасностью и удобством использования, вы можете создать отдельные токены для каждой формы.
Для этого создайте токен, но не открывайте его напрямую браузеру пользователя. Вместо этого хешируйте токен с именем файла формы, например так:
Когда вы получите запрос, сравните хеши. Если токен действителен и текущая форма действительна, хеши будут совпадать.
Anti-CSRF защита для каждого запроса
Если вам нужен очень высокий уровень защиты, вы можете использовать отдельные токены для каждого запроса. Это просто реализовать: все, что вам нужно сделать, это сделать токен недействительным после его проверки.
У такого подхода есть несколько недостатков для пользователей. Например, пользователи, которым нравится работать с несколькими вкладками, не смогут этого больше сделать. Кнопка возврата также прервет поток. Поэтому, прежде чем рассматривать этот подход, убедитесь, что он не повлияет отрицательно на пользовательский опыт. При создании токенов защиты от CSRF атаках на каждый запрос также учитывайте производительность сервера и используйте менее ресурсоемкие генераторы случайных чисел.
Использование непостоянных токенов
Если ваша веб-страница или веб-приложение очень загружены, а хранилище на сервере ограничено, вы, вероятно, захотите избежать сохранения токенов на стороне сервера. В этих случаях вы можете генерировать и обрабатывать токены криптографически. При таком подходе нет необходимости хранить токен в сеансе сервера:
Обратите внимание, что хотя этот метод поможет вам избежать хранения большого количества информации, но он может иметь накладные расходы на производительность, поскольку криптографические функции потребляют больше ресурсов, чем простая генерация случайных чисел.
Другой вариант для непостоянных токенов — файлы cookie с двойной отправкой. В этом методе сервер устанавливает случайное значение в файле cookie для пользователя еще до его аутентификации. Затем сервер ожидает, что это значение будет отправляться с каждым запросом (например, с использованием значения скрытой формы).
CSRF защита для Ajax
Токены Anti-CSRF также следует использовать для запросов Ajax. Однако перед тем, как реализовать какой-либо тип защиты CSRF для Ajax, убедитесь, что ваш веб-сервер не разрешает междоменные запросы Ajax (проверьте заголовки Cross-Origin Resource Sharing).
В случае Ajax вы можете включить свой токен в скрытое текстовое поле или непосредственно в JavaScript. Затем вы отправляете токен с каждым запросом Ajax и проверяете его присутствие на стороне сервера.
Anti-CSRF токены для формы входа
Принято считать, что Anti-CSRF токены необходимы только тогда, когда пользователь вошел в систему. Поэтому формы входа обычно не используют никакой защиты CSRF. Несмотря на то, что невозможно выдать себя за пользователя до того, как он войдет в систему, отсутствие защиты CSRF для форм входа может привести к тому, что пользователя обманом заставят войти в систему в качестве злоумышленника и раскрыть конфиденциальную информацию. Например, атака может быть проведена следующим образом:
По этим причинам рекомендуется также включать anti-CSRF токены на все страницы входа.
Предотвращение CSRF атак за пределами токенов
Для углубленной защиты от CSRF вы можете комбинировать токены CSRF с другими подходами. Например, вы можете использовать настраиваемые заголовки для проверки запросов Ajax. Этот метод работает, потому что в соответствии с политикой одного источника для добавления заголовков запроса можно использовать только JavaScript из одного источника. Подробное обсуждение этого и других методов предотвращения CSRF см. OWASP Cross-Site Request Forgery Prevention Cheat Sheet.
Токены Anti-CSRF — один из самых безопасных способов защиты от атак CSRF, но в некоторых случаях их можно обойти. Например, если веб-приложение имеет уязвимость межсайтового сценария (XSS), злоумышленник может использовать ее для выполнения сценария, который незаметно извлекает новую версию формы с текущим токеном CSRF. Чтобы предотвратить это и обеспечить надежную безопасность веб-приложений, убедитесь, что вы проверяете свое веб-приложение на все типы уязвимостей, а не только на CSRF.
XSS- и CSRF-атаки — разбираем уязвимости
Авторизуйтесь
XSS- и CSRF-атаки — разбираем уязвимости
Noveo Developer
В контексте веб-безопасности есть два основных вектора атаки, которые необходимо учитывать: XSS и CSRF. Прежде чем рассказать о них, необходимо понимать дефолтную политику браузера насчёт взаимодействия между вкладками — точнее, взаимодействия между скриптами с разным origin’ами. Эта политика называется Same Origin Policy (SOP). Её центральное понятие — Origin (
источник) скрипта/документа. Он определяется комбинацией трёх понятий: протокола (http/https, etc.), хоста (my-website.com) и порта (например, 443 для https и 80 для http).
Вот примеры, которые браузер будет интерпретировать как скрипты с одинаковым origin’ом. Если на открытой вкладке присутствует 3 скрипта, origin’ы которых отличаются подобным образом, то браузер будет воспринимать их как скрипты с одним origin’ом:
А такие origin’ы будут считаться разными:
Важная особенность SOP: скрипт с одним origin’ом может посылать запросы на другой origin. Однако не сможет прочитать ответ на него. Чтение ответа будет заблокировано на уровне браузера. Если требуется заблокировать в том числе отправку запросов (скажем, вы не хотите, чтобы скрипты, загруженные на вашем сайте с других origin’ов, могли делать запрос на origin сайта), это тоже возможно реализовать посредством указания Content Security Policy. Но дефолтная политика (SOP) работает именно так.
XSS / JS-Injections
Наиболее часто встречающейся атакой является Cross-Site Scripting («Межсайтовый скриптинг»), или более удачное, на мой взгляд, название — JS-инъекции (по аналогии с SQL-инъекциями). Если в html-документ вставить строку, в которой будут использоваться элементы, похожие на html-теги, то браузер будет интерпретировать их как валидный html-код и исполнять его. Например, можно прописать с пустым src и добавить onerror=“alert(‘hacked’)” (так как src пустой, то браузер сразу перейдет к вызову onerror), внутри которого выполнить любой JS-код (имея доступ к localStorage и так далее). Также можно поместить вредоносный скрипт внутрь запроса query params в следующем виде:
Предотвращение JS-инъекций
В современных фреймворках (вроде Angular/React) изначально действует санитизация, которую в случае необходимости (если вы хотите запустить inline-скрипт из строки и уверены, что там не содержится ничего вредоносного) можно отключить. В React’е это делается посредством атрибута, подчеркивающего опасность вставки inline-скриптов:
В Angular’е можно за’inject’ить санитайзер и выбрать тот уровень санитизации, который подходит под ситуацию. Например, можно разрешить чтение стилей, но при этом экранировать любые скрипты.
Помимо санитизации существует Content Security Policy (CSP) Header. Через него можно явно задать, скрипты с каким origin’ом могут исполняться браузером на текущей странице. По дефолту Content Security Policy содержит значение *. То есть браузеру разрешено запускать скрипты с любым origin’ом, включая inline-скрипты без origin’а. Такие настройки считаются очень небезопасными, и рекомендуется всегда явно указывать, скрипты с каким origin’ом можно запустить на сайте. Явное указание ограниченного набора origin’ов заодно предотвращает исполнение inline-скриптов. Чтобы разрешить их исполнение, требуется явно это прописывать.
Пример того, как может выглядеть CSP Header:
Такие настройки означают, что изображения могут подгружаться с любого источника (*), media только с двух источников (media1.com & media2.com). А скриптам позволено запускаться, если они имеют только один origin (userscripts.example.com). default-src ‘self’ позволяет запускать скрипты с текущего origin’а, но не его поддоменов.
4–5 декабря, Онлайн, Беcплатно
Посредством CSP-заголовка можно очень тонко настраивать исполнение скриптов на сайте.
content-security-policy Header и access-control-allow-origin немного похожи. CSP позволяет обходить SOP, а access-control-allow-origin позволяет получать разрешение на CORS. То есть отвечать (response) на запросы скриптов с другим origin’ом.
В начале статьи я упоминал, что SOP позволяет скриптам с одним origin’ом делать запросы на другой origin, однако SOP заблокирует ответ. Посредством access-control-allow-origin можно получить доступ к этому ответу, если на сервере явно прописан origin, который имеет право получать ответы.
Если кратко и утрированно, то SCP — это про SOP и frontend-часть системы. А access-control-allow-otigin — про CORS и backend-часть.
CSRF (XSRF)
Второй по распространённости тип уязвимости — это Cross-Site Request Forgery («Межсетевая подделка запроса»). Этот вектор атаки использует склонность браузера неявно добавлять куки к любому запросу. Например, вы авторизовались на сайте, где используются куки, и в какой-то момент некий скрипт делает запрос на origin этого банка — то есть открыли почтовый клиент и перешли по вредоносной ссылке. Браузер автоматически добавит куки к запросу, даже если сам запрос происходит с другой вкладки.
Из-за SOP этот скрипт не будет иметь доступа к response. Но он сможет выполнять запросы на правах авторизованного пользователя. Например, сделать запрос на перевод денег или просто на удаление любой возможной информации.
Для предотвращения этой атаки в первую очередь рекомендуется использовать явные системы аутентификации. Например, session token / jwt в header или session token в body param. Также, если на сайте используется какая-то форма, то рекомендуется реализовывать anti-csrf token’ы. Их суть в том, что сервер в response отдаёт два случайных токена. Один предназначен для куков, другой прячется в скрытом поле формы. Когда клиент submit’ит форму, то должен отправить оба токена обратно на сервер. В случае, если они отличаются от того, что сервер выпустил изначально, сервер блокирует запрос.
Integrity
В контексте информационной безопасности существует понятие CIA triad, объединяющее три аспекта:
В web’е это можно представить в виде отношений между frontend’ом и backend’ом. В html есть специальный атрибут integrity, позволяющий запускать скрипт только в том случае, если он не отличается от того, что изначально подразумевали его разработчики.
Предположим, что вы используете cdn (content delivery network) для оптимизации скорости доставки приложения, однако вы хотите быть уверены, что приложение, которое вы сбилдили сами, и то, которое получаете из cdn, — одно и то же. В этом случае можно в процессе прод-билда приложения сгенерировать integrity-хеш, который указывается следующим образом:
Что такое токен CSRF? Каково его значение и как оно работает?
Ладно, ребята, я пишу приложение для Django и просто хочу понять, что на самом деле представляет собой токен csrf и как он защищает данные. Являются ли почтовые данные небезопасными, если вы не используете токены csrf?
Я знаю, как использовать csrf_token, но мне просто нужно немного информации, как это работает.
Решение
Подделка межсайтовых запросов (CSRF) простыми словами
Это мир без токенов CSRF.
Теперь к лучшему с Токены CSRF:
Результат: Вы держите свой 10000 денежные единицы. Я предлагаю вам пожертвовать часть этого в Википедии.
(Ваш пробег может отличаться.)
РЕДАКТИРОВАТЬ из комментария стоит прочитать:
Стоит отметить, что сценарий из www.cute-cat-pictures.org обычно не имеет доступа к вашему токену анти-CSRF от www.mybank.com из-за контроля доступа HTTP. Эта заметка важна для некоторых людей, которые необоснованно отправляют заголовок Access-Control-Allow-Origin: * за каждый ответ сайта, не зная, для чего он нужен, просто потому, что они не могут использовать API с другого сайта.
Другие решения
Да, почтовые данные в безопасности. Но происхождение этих данных не так. Таким образом, кто-то может заставить пользователя с помощью JS войти на ваш сайт, просматривая веб-страницу злоумышленника.
Чтобы предотвратить это, django отправит случайный ключ как в файле cookie, так и в данных формы.
Затем, когда пользователи отправляют сообщения POST, он проверяет, идентичны ли два ключа. В случае обмана пользователя сторонний веб-сайт не может получить файлы cookie вашего сайта, что приводит к ошибке аутентификации.
Сайт генерирует уникальный токен при создании страницы формы. Этот токен необходим для отправки / получения данных на сервер.
Поскольку токен генерируется вашим сайтом и предоставляется только при создании страницы с формой, какой-то другой сайт не может имитировать ваши формы — он не будет иметь токен и, следовательно, не сможет публиковать на вашем сайте.
Позволь мне привести пример…
Представьте, что у вас есть веб-сайт, похожий на упрощенный Twitter, размещенный на a.com. Пользователи, вошедшие в систему, могут вводить некоторый текст (твит) в форму, которая отправляется на сервер в виде запроса POST и публикуется при нажатии кнопки отправки. На сервере пользователь идентифицируется cookie-файлом, содержащим его уникальный идентификатор сеанса, поэтому ваш сервер знает, кто опубликовал твит.
Форма может быть такой простой:
А теперь представьте, что плохой парень копирует и вставляет эту форму на свой вредоносный веб-сайт, скажем, на b.com. Форма все еще будет работать. Пока пользователь входит в ваш Твиттер (т. Е. У него есть действительный файл cookie сеанса для a.com), запрос POST будет отправляться на http://a.com/tweet и обрабатывается как обычно, когда пользователь нажимает кнопку отправки.
Пока что это не большая проблема, если пользователь знает о том, что именно делает форма, но что если наш плохой парень подправит форму следующим образом:
Теперь, если один из ваших пользователей попадает на сайт злоумышленника и нажимает кнопку «Нажмите, чтобы выиграть!», Форма отправляется на ваш сайт, пользователь правильно идентифицируется по идентификатору сеанса в файле cookie, и скрытый твит получает опубликован.
Если бы нашему плохому парню было еще хуже, он заставил бы невинного пользователя отправить эту форму, как только они откроют его веб-страницу с помощью JavaScript, возможно, даже полностью скрытого в невидимом фрейме. Это в основном подделка межсайтовых запросов.
Форма может быть легко представлена отовсюду и везде. Обычно это общая черта, но во многих случаях важно разрешить отправку формы только из домена, к которому она принадлежит.
Как мне убедиться, что форму можно отправить только с моего собственного сайта?
Вот где появляется токен CSRF. Маркер CSRF — это случайная, трудно угадываемая строка. На странице с формой, которую вы хотите защитить, сервер сгенерирует случайную строку, токен CSRF, добавит ее в форму в качестве скрытого поля и также каким-то образом запомнит, либо сохранив ее в сеансе, либо установив файл cookie. содержащий значение. Теперь форма будет выглядеть так:
Когда пользователь отправляет форму, сервер просто должен сравнить значение отправленного поля csrf-token (имя не имеет значения) с токеном CSRF, запомненным сервером. Если обе строки равны, сервер может продолжить обработку формы. В противном случае сервер должен немедленно прекратить обработку формы и ответить ошибкой.
Почему это работает?
Есть несколько причин, по которым злоумышленник из нашего примера не может получить токен CSRF:
Копирование статического исходного кода с нашей страницы на другой веб-сайт было бы бесполезным, поскольку значение скрытого поля меняется с каждым пользователем. Если бы сайт злоумышленника не знал токен CSRF текущего пользователя, ваш сервер всегда отклонял бы запрос POST.
Поскольку вредоносная страница злоумышленника загружается браузером вашего пользователя из другого домена (b.com вместо a.com), у злоумышленника нет шансов написать код JavaScript, который загружает контент и, следовательно, текущий токен CSRF нашего пользователя из Ваш сайт. Это связано с тем, что веб-браузеры по умолчанию не разрешают междоменные запросы AJAX.
Плохой парень также не может получить доступ к cookie, установленному вашим сервером, потому что домены не будут совпадать.
Когда следует защищать от подделки межсайтовых запросов?
Если вы можете быть уверены, что не смешиваете GET, POST и другие методы запросов, как описано выше, хорошим началом будет защита всех запросов POST по умолчанию.
Вам не нужно защищать запросы PUT и DELETE, потому что, как описано выше, стандартная HTML-форма не может быть отправлена браузером с использованием этих методов.
Это означает, что часто вам даже не нужно добавлять токен CSRF в запросы AJAX, даже если они являются запросами POST, но вам нужно будет убедиться, что вы обходите проверку CSRF только в своем веб-приложении, если запрос POST на самом деле AJAX запрос. Вы можете сделать это, посмотрев на наличие заголовка, такого как X-Requested-With, который обычно включают в себя запросы AJAX. Вы также можете установить другой пользовательский заголовок и проверить его наличие на стороне сервера. Это безопасно, потому что браузер не будет добавлять пользовательские заголовки к обычной отправке формы HTML (см. Выше), поэтому у мистера Бад Гая нет шансов смоделировать это поведение с помощью формы.
Если у вас есть сомнения по поводу запросов AJAX, поскольку по какой-то причине вы не можете проверить заголовок, такой как X-Requested-With, просто передайте сгенерированный токен CSRF в свой JavaScript и добавьте токен в запрос AJAX. Есть несколько способов сделать это; либо добавьте его в полезную нагрузку, как обычная форма HTML, либо добавьте пользовательский заголовок в запрос AJAX. Пока ваш сервер знает, где искать его во входящем запросе и может сравнить его с исходным значением, которое он запоминает из сеанса или файла cookie, вы будете отсортированы.
Корень всего этого — убедиться, что запросы поступают от реальных пользователей сайта. Токен csrf создается для форм и должен быть привязан к сеансам пользователя. Используется для отправки запросов на сервер, на котором токен их проверяет. Это один из способов защиты от csrf, другим будет проверка заголовка реферера.