CSRF и CORS: правильная защита браузерных запросов

Security2026-09-14TryQuickToolBox

Вы создали веб-приложение с чистым API, но затем замечаете странные запросы в логах — или, что хуже, сканер безопасности помечает ваш сайт из-за ошибок в настройках CSRF и CORS. Эти две аббревиатуры часто путают, но они решают разные задачи. Непонимание их различий может сделать ваших пользователей уязвимыми или нарушить легитимные кросс-доменные запросы.

В этой статье мы разберём, что такое CSRF и CORS на самом деле, как они взаимодействуют с безопасностью браузера, и дадим конкретные шаги для защиты ваших приложений без потери функциональности.

Что такое CSRF и почему это важно?

Межсайтовая подделка запроса (CSRF) — это атака, которая заставляет браузер пользователя отправить запрос на сайт, где он аутентифицирован. Представьте, что вы вошли в свой банк на bank.com. Затем вы посещаете вредоносный сайт, содержащий тег изображения вроде <img src="https://bank.com/transfer?to=attacker&amount=1000">. Ваш браузер автоматически включает cookies банка в запрос, и если банк не имеет защиты от CSRF, перевод проходит.

Ключевой момент: CSRF эксплуатирует доверие сайта к браузеру пользователя. Злоумышленнику не нужно красть вашу сессию; ему достаточно, чтобы ваш браузер сделал запрос от вашего имени.

Как работают CSRF-атаки

Для успеха CSRF-атаки должны быть выполнены три условия:

Обычные цели — операции, изменяющие состояние: смена email, перевод средств, публикация контента или изменение прав доступа.

Что такое CORS и зачем он существует?

Cross-Origin Resource Sharing (CORS) — это механизм браузера, который разрешает или запрещает веб-страницам делать запросы к домену, отличному от того, который обслуживал страницу. Это расширение политики одного источника (Same-Origin Policy, SOP), которая ограничивает взаимодействие документа или скрипта, загруженного из одного источника, с ресурсами из другого источника.

Без CORS вредоносный сайт мог бы использовать JavaScript для чтения данных из API вашего банка, если вы авторизованы. CORS даёт серверам способ явно разрешать определённые кросс-доменные запросы.

Политика одного источника (SOP)

Два URL имеют один источник, если совпадают протокол, хост и порт. Например, https://example.com/app и https://example.com/api имеют один источник, а http://example.com (другой протокол) и https://api.example.com (другой хост) — нет.

SOP запрещает скриптам из одного источника читать ответы из другого источника. CORS ослабляет это ограничение, добавляя HTTP-заголовки, которые сообщают браузеру, разрешать ли запрос.

CSRF vs CORS: ключевые различия

Важно понимать, что CSRF и CORS не противоположны; они решают разные задачи безопасности. CSRF — о предотвращении несанкционированных запросов, изменяющих состояние, а CORS — о контроле того, какие источники могут читать ответы.

Аспект CSRF CORS
Основная цель Предотвратить поддельные запросы Контролировать кросс-доменное чтение
Вектор атаки Вредоносный сайт инициирует запросы Вредоносный сайт читает ответы
Механизм защиты Токены, SameSite cookies HTTP-заголовки (Access-Control-*)
Принудительно браузером Нет (сервер должен проверять) Да (браузер блокирует чтение)

Как защититься от CSRF

Существует несколько проверенных стратегий для смягчения CSRF. Вам не нужны все, но многоуровневая защита разумна.

1. Используйте анти-CSRF токены

Самая надёжная защита — включить уникальный, непредсказуемый токен в каждый запрос, изменяющий состояние. Сервер проверяет токен перед обработкой. Токены должны быть привязаны к сессии пользователя и не раскрываться в URL (чтобы избежать утечки через заголовки referrer).

// Пример: генерация и проверка CSRF-токена в Node.js/Express
const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });

app.get('/form', csrfProtection, (req, res) => {
  res.render('form', { csrfToken: req.csrfToken() });
});

app.post('/process', csrfProtection, (req, res) => {
  // Токен проверяется автоматически
  res.send('OK');
});

2. Установите SameSite cookies

Современные браузеры поддерживают атрибут SameSite для cookies. Установка его в Lax или Strict предотвращает отправку cookies браузером при кросс-сайтовых запросах, что блокирует многие CSRF-атаки. Lax разрешает cookies при навигации верхнего уровня (например, клик по ссылке), а Strict блокирует все кросс-сайтовые запросы.

Set-Cookie: sessionId=abc123; SameSite=Lax; Secure; HttpOnly

3. Проверяйте заголовки Origin и Referer

Проверяйте заголовок Origin или Referer во входящих запросах. Если они не совпадают с ожидаемым доменом, отклоняйте запрос. Это простой, но эффективный дополнительный уровень защиты.

4. Используйте кастомные заголовки для AJAX

Если ваш API используется через JavaScript, требуйте кастомный заголовок вроде X-Requested-With. Браузеры применяют CORS preflight для кастомных заголовков, поэтому простой POST-запрос формы с вредоносного сайта не будет его содержать.

Правильная настройка CORS

Неправильная конфигурация CORS также может привести к проблемам безопасности. Самая распространённая ошибка — установка Access-Control-Allow-Origin: * при одновременном разрешении учётных данных. Такая комбинация запрещена браузерами, но разработчики иногда пытаются обойти это небезопасным способом.

Лучшие практики для заголовков CORS

# Пример: конфигурация Nginx для CORS
location /api/ {
  if ($http_origin ~* (https://(app|admin)\.example\.com)) {
    add_header 'Access-Control-Allow-Origin' $http_origin;
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
  }
  if ($request_method = 'OPTIONS') {
    return 204;
  }
}

Помните, что CORS применяется браузером, а не сервером. Это не замена аутентификации или авторизации; это способ безопасно ослабить политику одного источника.

Собираем всё вместе

Защита браузерных запросов требует многоуровневого подхода. Вот краткий чек-лист:

  1. Используйте анти-CSRF токены для всех операций, изменяющих состояние.
  2. Установите SameSite cookies в Lax или Strict.
  3. Проверяйте заголовки Origin/Referer на сервере.
  4. Настройте CORS точно: белый список источников, ограничение методов и отказ от wildcard с учётными данными.
  5. Регулярно тестируйте ваше приложение сканерами безопасности и вручную.

Понимая различные роли CSRF и CORS, вы сможете избежать распространённых ошибок и создать более безопасное веб-приложение.

FAQ

Может ли CORS предотвратить CSRF-атаки?

Нет, CORS не предотвращает CSRF. CSRF-атаки не полагаются на чтение ответов; они просто инициируют запросы. CORS контролирует, какие источники могут читать ответы, но не блокирует отправку запроса. Для предотвращения CSRF нужны токены, SameSite cookies или проверка источника.

Безопасно ли устанавливать Access-Control-Allow-Origin в '*'?

Установка '*' безопасна только если ваш API не использует учётные данные (cookies, HTTP-аутентификацию). Если задействованы учётные данные, браузеры отклонят ответ. Для аутентифицированных API всегда указывайте точные источники.

Нужна ли мне защита от CSRF, если я использую JWT в заголовках Authorization?

Если вы храните JWT в cookies, защита от CSRF всё ещё нужна, потому что cookies отправляются автоматически. Если вы храните JWT в памяти и отправляете их через заголовок Authorization, CSRF не является проблемой, поскольку злоумышленник не может установить кастомные заголовки кросс-доменно. Однако вы должны защищаться от XSS, чтобы сохранить токен в безопасности.

Готовы протестировать заголовки CORS вашего API? Используйте наш Nginx Log Analyzer для анализа шаблонов запросов и выявления подозрительных кросс-доменных попыток.