Перевод статьи: Netsparker Security Team — How to Protect Your Website Using Anti-CSRF Tokens
Токены Anti-CSRF (или просто токены CSRF) — это уникальные значения, используемые в веб-приложениях для предотвращения атак с подделкой межсайтовых запросов (CSRF / XSRF). CSRF-атаки — это атаки на стороне клиента, которые могут использоваться для перенаправления пользователей на вредоносный веб-сайт, кражи конфиденциальной информации или выполнения других действий в рамках сеанса пользователя. В этой статье рассказано, как использовать токены CSRF для защиты пользователей от атак CSRF и их последствий.
Основной принцип, лежащий в основе токенов anti-CSRF (также известных как шаблоны токенов синхронизатора), заключается в том, чтобы предоставить браузеру пользователя уникальную информацию (токен) и проверить, отправляет ли веб-браузер ее обратно. Токен должен быть уникальным и его невозможно угадать третьим лицам. Приложение не должно работать, если оно не проверит эту информацию. Таким образом, только исходный пользователь может отправлять запросы в аутентифицированном сеансе.
Допустим, вы запускаете веб-приложение социальной сети на сайте www.example.com. Чтобы опубликовать сообщение в своем профиле, пользователь заполняет HTML-форму и нажимает кнопку «Отправить».
<form action="/action.php" method="post">
Subject: <input type="text" name="subject"/><br/>
Content: <input type="text" name="content"/><br/>
<input type="submit" value="Submit"/>
</form>
Это заставляет веб-браузер отправлять POST запрос:
POST /post.php HTTP/1.1
Host: example.com
subject=subject&content=content
Если пользователь вошел в систему и злоумышленник знает синтаксис этого запроса, злоумышленник может использовать CSRF-атаку для публикации рекламы в профиле пользователя:
<form action="/action.php" method="post">
Subject: <input type="text" name="subject" value="Buy my product!"/>
Content: <input type="text" name="content" value="To buy my product, visit this site: example.biz."/>
<input type="submit" value="Submit"/>
</form>
<script>
document.forms[0].submit();
</script>
В результате веб-браузер отправляет следующий POST запрос:
POST /post.php HTTP/1.1
Host: example.com
subject=Buy my product!&content=To buy my product, visit this site: example.biz.
Если ваш сайт использует простой токен anti-CSRF, веб-сервер устанавливает этот токен в cookie сеанса вашего веб-браузера сразу после входа в систему. Все отправленные формы через скрытое поле (hidden field), будут содержать этот токен. Таким образом это полностью устраняет уязвимость CSRF.
<form>
Subject: <input type="text" name="subject"/><br/>
Content: <input type="text" name="content"/><br/>
<input type="submit" value="Submit"/>
<input type="hidden" name="token" value="R6B7hoBQd0wfG5Y6qOXHPNm4b9WKsTq6Vy6Jssxb"/>
</form>
Затем сервер проверит, содержит ли каждый POST запрос требуемый токен:
POST /post.php HTTP/1.1
Host: example.com
subject=I am feeling well&content=I just ate a cookie and it was delicious.&token=R6B7hoBQd0wfG5Y6qOXHPNm4b9WKsTq6Vy6Jssxb
Если злоумышленник попытается выполнить подделку межсайтового запроса с помощью вредоносного сайта, он не узнает текущий токен, установленный в cookie. Ваш сервер не станет обрабатывать запрос без этого токена, поэтому атака не удастся.
Когда вы создаете и позже проверяете свой токен, следуйте этим принципам, чтобы убедиться, что ваш anti-CSRF токен не может быть угадан или использован иным образом:
Например, в PHP вы можете сгенерировать токен следующим образом:
$_SESSION['token'] = bin2hex(random_bytes(24));
И проверьте токен следующим образом:
if (hash_equals($_SESSION['token'], $_POST['token'])) {
// Action if token is valid
} else {
// Action if token is invalid
}
Описанный выше токен анти-CSRF устанавливается при входе в систему в файле cookie сеанса пользователя, а затем проверяется каждой формой. В большинстве случаев этой защиты достаточно. Однако некоторые сайты предпочитают использовать более безопасный подход. Чтобы достичь хорошего компромисса между безопасностью и удобством использования, вы можете создать отдельные токены для каждой формы.
Для этого создайте токен, но не открывайте его напрямую браузеру пользователя. Вместо этого хешируйте токен с именем файла формы, например так:
hash_hmac('sha256', 'post.php', $_SESSION['internal_token'])
Когда вы получите запрос, сравните хеши. Если токен действителен и текущая форма действительна, хеши будут совпадать.
Если вам нужен очень высокий уровень защиты, вы можете использовать отдельные токены для каждого запроса. Это просто реализовать: все, что вам нужно сделать, это сделать токен недействительным после его проверки.
У такого подхода есть несколько недостатков для пользователей. Например, пользователи, которым нравится работать с несколькими вкладками, не смогут этого больше сделать. Кнопка возврата также прервет поток. Поэтому, прежде чем рассматривать этот подход, убедитесь, что он не повлияет отрицательно на пользовательский опыт. При создании токенов защиты от CSRF атаках на каждый запрос также учитывайте производительность сервера и используйте менее ресурсоемкие генераторы случайных чисел.
Если ваша веб-страница или веб-приложение очень загружены, а хранилище на сервере ограничено, вы, вероятно, захотите избежать сохранения токенов на стороне сервера. В этих случаях вы можете генерировать и обрабатывать токены криптографически. При таком подходе нет необходимости хранить токен в сеансе сервера:
Обратите внимание, что хотя этот метод поможет вам избежать хранения большого количества информации, но он может иметь накладные расходы на производительность, поскольку криптографические функции потребляют больше ресурсов, чем простая генерация случайных чисел.
Другой вариант для непостоянных токенов — файлы cookie с двойной отправкой. В этом методе сервер устанавливает случайное значение в файле cookie для пользователя еще до его аутентификации. Затем сервер ожидает, что это значение будет отправляться с каждым запросом (например, с использованием значения скрытой формы).
Токены Anti-CSRF также следует использовать для запросов Ajax. Однако перед тем, как реализовать какой-либо тип защиты CSRF для Ajax, убедитесь, что ваш веб-сервер не разрешает междоменные запросы Ajax (проверьте заголовки Cross-Origin Resource Sharing).
В случае Ajax вы можете включить свой токен в скрытое текстовое поле или непосредственно в JavaScript. Затем вы отправляете токен с каждым запросом Ajax и проверяете его присутствие на стороне сервера.
Принято считать, что Anti-CSRF токены необходимы только тогда, когда пользователь вошел в систему. Поэтому формы входа обычно не используют никакой защиты CSRF. Несмотря на то, что невозможно выдать себя за пользователя до того, как он войдет в систему, отсутствие защиты CSRF для форм входа может привести к тому, что пользователя обманом заставят войти в систему в качестве злоумышленника и раскрыть конфиденциальную информацию. Например, атака может быть проведена следующим образом:
По этим причинам рекомендуется также включать anti-CSRF токены на все страницы входа.
Для углубленной защиты от CSRF вы можете комбинировать токены CSRF с другими подходами. Например, вы можете использовать настраиваемые заголовки для проверки запросов Ajax. Этот метод работает, потому что в соответствии с политикой одного источника для добавления заголовков запроса можно использовать только JavaScript из одного источника. Подробное обсуждение этого и других методов предотвращения CSRF см. OWASP Cross-Site Request Forgery Prevention Cheat Sheet.
Токены Anti-CSRF — один из самых безопасных способов защиты от атак CSRF, но в некоторых случаях их можно обойти. Например, если веб-приложение имеет уязвимость межсайтового сценария (XSS), злоумышленник может использовать ее для выполнения сценария, который незаметно извлекает новую версию формы с текущим токеном CSRF. Чтобы предотвратить это и обеспечить надежную безопасность веб-приложений, убедитесь, что вы проверяете свое веб-приложение на все типы уязвимостей, а не только на CSRF.
Краткий перевод: https://vuejs.org/guide/components/v-model.html Основное использование v-model используется для реализации двусторонней привязки в компоненте. Начиная с Vue…
Сегодня мы рады объявить о выпуске Vue 3.4 «🏀 Slam Dunk»! Этот выпуск включает в…
Vue.js — это универсальный и адаптируемый фреймворк. Благодаря своей отличительной архитектуре и системе реактивности Vue…
Недавно, у меня истек сертификат и пришлось заказывать новый и затем устанавливать на хостинг с…
Каким бы ни было ваше мнение о JavaScript, но всем известно, что работа с датами…
Все, кто следит за последними событиями в мире адаптивного дизайна, согласятся, что введение контейнерных запросов…