Подделка межсайтовых запросов (CORS) — это уязвимость, которая позволяет злоумышленнику воспользоваться сеансом пользователя, вошедшего в систему на доверенном веб-сайте, и отправлять несанкционированные запросы на другой веб-сайт, которому пользователь доверяет.
WTForms — это расширение Flask, которое по умолчанию интегрирует защиту CSRF для предотвращения атак CORS.
В этой статье мы будем использовать WTForms для интеграции защиты от CSRF в наше веб-приложение Flask, чтобы сделать наше приложение устойчивым к атакам CORS.
Реальные сценарии уязвимостей CSRF
1. Предположим, что пользователь вошел в свой аккаунт онлайн-банкинга и одновременно зашел на вредоносный сайт. На вредоносном сайте есть скрытая форма, которая при отправке переводит средства со счета пользователя на счет злоумышленника.
- Без защиты от CSRF злоумышленник может создать такую форму, которая будет отправлена автоматически.
- Поскольку пользователь вошел в систему и аутентифицировался в своей учетной записи, запрос успешно обрабатывается без ведома пользователя.
2. Эту проблему можно решить, внедрив защиту CSRF, например, предоставляемую WTForms для приложений Flask. Это снижает риск, требуя уникальный токен для каждой отправки формы, без токена запрос на отправку формы будет отклонен, что предотвращает несанкционированные действия, даже если пользователь аутентифицирован.
3. Аналогично описанному выше сценарию предположим, что пользователь вошел в свою учетную запись интернет-магазина и одновременно зашел на вредоносный веб-сайт, на котором есть скрытая форма, при заполнении которой он добавляет дорогие товары и размещает заказ на платформе интернет-магазина.
- Без защиты от CSRF злоумышленник может создать такую форму, которая отправляет запросы на добавление товаров в корзину пользователя, когда тот посещает вредоносный сайт.
- Поскольку пользователь аутентифицирован на своей платформе интернет-магазина, запрос успешно обрабатывается без ведома пользователя.
4. Эту проблему можно решить, внедрив защиту от CSRF-атак, которая снижает риск, требуя уникальный токен для каждой отправки формы. Без токена запрос на отправку формы будет отклонен, что предотвращает несанкционированные действия, даже если пользователь аутентифицирован.
Примените защиту CSRF к вашему приложению Flask
В этом разделе мы защитим наше приложение, применив защиту от CSRF с помощью пакета flask-wtf.
1. Установите пакет flask-wtf.
(myenv) $ sudo pip install flask-wtf
2. Убедитесь, что вы находитесь в каталоге проекта.
(myenv) $ cd sample
3. Откройте файл app.py.
(myenv) $ nano app.py
4. Импортируйте модуль CSRFProtect в начало файла.
from flask_wtf.csrf import CSRFProtect
5. Добавьте следующие конфигурации в app.py перед маршрутами.
app.config['SECRET_KEY'] = 'your_secret_key_here'
csrf = CSRFProtect(app)
csrf._csrf_request_token_key = 'X-CSRFToken'
В приведенном выше коде мы настраиваем секретный ключ и включаем защиту CSRF для нашего веб-приложения Flask. Обязательно замените your_secret_key_here на фактический секретный ключ для вашего приложения.
Сохраните и выйдите из файла.
6. Перейдите в каталог шаблонов.
(myenv) $ cd templates
7. Откройте файл index.html.
(myenv) $ nano index.html
8. Отредактируйте HTML-страницу <body>, включив в нее конфигурацию CSRF с помощью WTForms.
<div class="container mt-5">
<h1 class="text-center mb-4">To-Do App</h1>
<form id="task-form">
<input type="hidden" name="csrf_token" value="{{ csrf_token()}}">
<div class="input-group mb-3">
<input type="text" id="task-input" class="form-control" placeholder="Enter a task">
<div class="input-group-append">
<button id="add-task" class="btn btn-primary">Add Task</button>
</div>
</div>
</form>
<ul id="task-list" class="list-group">
</ul>
</div>
<script>
var csrfToken = $('input[name="csrf_token"]').val();
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) &&!this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrfToken);
}
}
});
</script>
В приведенном выше коде:
- Мы добавили форму, которая включает скрытое поле ввода с функцией csrf_token(), которая генерирует токен CSRF, имеющий решающее значение для защиты от CSRF.
- Кроме того, функция beforesend срабатывает перед каждым запросом AJAX.
- HTTP-заголовок с именем X-CSRFToken устанавливается со значением токена CSRF. Это гарантирует, что токен CSRF будет отправлен с любыми запросами, которые могут изменить данные на сервере.
Сохраните и выйдите из файла.
9. Выйдите из каталога шаблонов.
(myenv) $ cd..
Заключение
В этой статье мы защитили наше веб-приложение Flask от атак CORS, применив защиту CSRF с помощью WTForms. Важно принимать меры безопасности в производственных приложениях, чтобы защитить основные ресурсы приложения от вредоносных атак.