CSRF и токены защиты
CSRF (Cross-Site Request Forgery) заставляет браузер жертвы выполнить действие на сайте, где она уже залогинена, — без её ведома.
Почему это возможно
Когда вы вошли на сайт, браузер хранит сессионную куку и автоматически прикрепляет её ко всем запросам на этот сайт. Если злоумышленник заманит вас на свою страницу, та может отправить запрос на «доверенный» сайт — и браузер послушно приложит вашу куку. Сервер увидит валидную сессию и выполнит действие.
Что отличает CSRF от XSS
CSRF не крадёт данные и не выполняет скрипт на странице жертвы. Он злоупотребляет тем, что аутентификация по куке происходит автоматически. Поэтому защита строится вокруг проверки «а правда ли этот запрос пришёл с нашей формы».
Защита: CSRF-токены
Сервер выдаёт каждой форме секретный одноразовый токен, который чужой сайт не может угадать. При отправке формы токен возвращается, и сервер сверяет его. Чужая страница токена не знает — запрос отклоняется.
import secrets
# Сервер генерирует токен и кладёт его в форму и в сессию
csrf_token = secrets.token_hex(16)
session = {"csrf": csrf_token}
# При получении формы сервер сверяет присланный токен с сохранённым
def check_request(form_token, session):
return secrets.compare_digest(form_token, session["csrf"])
print("Правильный токен принят:", check_request(csrf_token, session))
print("Подделанный токен принят:", check_request("00000000", session))Используем compare_digest для сравнения, устойчивого к атакам по времени.
Современные слои защиты
- CSRF-токены — классика, встроена во фреймворки (Django, Flask-WTF и др.).
- Куки с атрибутом SameSite (Lax/Strict) — браузер не отправляет куку при межсайтовых запросах.
- Проверка заголовков
Origin/Refererкак дополнительный сигнал.
Главное правило: меняющие данные действия (POST/PUT/DELETE) должны требовать подтверждения, которое нельзя подделать с чужого сайта.