CSRF (Cross-Site Request Forgery)

CSRF — это тип атаки, при которой злоумышленник заставляет пользователя выполнить нежелательные действия в веб-приложении, где пользователь в данный момент аутентифицирован.

Как работает CSRF

  1. Пользователь аутентифицирован на сайте A
  2. Пользователь посещает злонамеренный сайт B
  3. Сайт B отправляет запрос на сайт A от имени пользователя
  4. Браузер автоматически добавляет cookies для сайта A
  5. Сайт A выполняет действие, думая что запрос от пользователя

Пример CSRF атаки

 1<!-- Злонамеренная страница -->
 2<img src="https://bank.com/transfer?to=attacker&amount=1000" />
 3
 4<!-- Или через форму -->
 5<form action="https://bank.com/transfer" method="POST" style="display:none;">
 6  <input name="to" value="attacker" />
 7  <input name="amount" value="1000" />
 8  <input type="submit" />
 9</form>
10<script>
11  document.forms[0].submit();
12</script>

Методы защиты от CSRF

  • CSRF токены — уникальные токены для каждого запроса
  • SameSite cookies — ограничение отправки cookies
  • Referer проверка — проверка источника запроса
  • Double Submit Cookies — токен в cookie и параметре
  • Custom Headers — добавление кастомных заголовков

CSRF Token реализация

1# Django пример
2<form method="post">
3  {% csrf_token %}
4  <input name="email" type="email" />
5  <button type="submit">Subscribe</button>
6</form>
1# Express.js с csurf middleware
2const csrf = require('csurf');
3const csrfProtection = csrf({ cookie: true });
4
5app.use(csrfProtection);
6
7app.get('/form', (req, res) => {
8  res.render('form', { csrfToken: req.csrfToken() });
9});

SameSite Cookies

1# Установка SameSite атрибута
2Set-Cookie: sessionid=abc123; SameSite=Strict
3Set-Cookie: sessionid=abc123; SameSite=Lax
4Set-Cookie: sessionid=abc123; SameSite=None; Secure
1# Express.js настройка
2app.use(session({
3  cookie: {
4    sameSite: 'strict', // или 'lax', 'none'
5    secure: true, // только для HTTPS
6    httpOnly: true
7  }
8}));

Проверка Referer заголовка

 1// Node.js пример
 2function checkReferer(req, res, next) {
 3  const referer = req.get('Referer');
 4  const host = req.get('Host');
 5
 6  if (!referer || !referer.includes(host)) {
 7    return res.status(403).send('Invalid referer');
 8  }
 9
10  next();
11}

Тестирование на CSRF

  • Создайте форму на стороннем сайте
  • Попробуйте выполнить действия без CSRF токена
  • Используйте инструменты как Burp Suite, OWASP ZAP
  • Проверьте настройки SameSite cookies

FAQ

В чем разница между CSRF и XSS?

XSS выполняет код в браузере жертвы на том же сайте, CSRF заставляет браузер выполнить запрос на другой сайт от имени пользователя.