CORS и Security в REST API
Введение: пропускной пункт у здания 🛂
REST API — как офис с охраной: важно знать, кто входит, откуда и с какими правами.
Если не настроить CORS и базовую безопасность, браузер блокирует запросы, а злоумышленники находят дырки.
💡 Совет: начинайте с правил доступа, а потом добавляйте защиту от атак.
✅ Вывод: CORS решает «кто может обращаться», Security — «как не дать украсть данные».
Если не настроить CORS и базовую безопасность, браузер блокирует запросы, а злоумышленники находят дырки.
💡 Совет: начинайте с правил доступа, а потом добавляйте защиту от атак.
✅ Вывод: CORS решает «кто может обращаться», Security — «как не дать украсть данные».
Проблема → решение
Проблема: фронтенд и API на разных доменах, браузер блокирует запросы, а атаки (CSRF, XSS, SQLi) ломают безопасность.
Решение: чёткие CORS‑правила + базовые меры защиты (HTTPS, валидация, ограничения, защита токенов).
✅ Вывод: правила доступа и защита должны идти вместе.
Решение: чёткие CORS‑правила + базовые меры защиты (HTTPS, валидация, ограничения, защита токенов).
✅ Вывод: правила доступа и защита должны идти вместе.
Чем помогает и как работает
CORS и Security помогают:
- безопасно разрешать нужные домены;
- снижать риск утечек токенов и данных;
- защищать API от типовых атак.
Как это работает:
- Браузер проверяет origin и решает, нужен ли CORS.
- Для сложных запросов отправляет preflight (OPTIONS).
- Сервер отв��чает CORS‑заголовками (origin, методы, headers, credentials).
- Только после этого отправляется основной запрос.
- API проверяет авторизацию, валидирует данные и применяет защитные правила (HTTPS, CSRF, XSS/SQLi, rate limit).
✅ Вывод: CORS открывает «дверь», а security‑правила решают, кого пускать и как защищаться.
Ключевые термины (простыми словами)
- Origin (источник) — домен + протокол + порт.
- Same‑Origin Policy (политика одинакового источника) — браузер разрешает запросы только к «своему» origin.
- CORS (междоменный доступ) — набор заголовков, который расширяет правила SOP.
- Preflight (предварительный запрос) — автоматический OPTIONS для проверки разрешений.
- Credentials (учётные данные) — cookies и авторизационные заголовки.
- CSRF (подделка межсайтового запроса) — атака через автоматическую отправку cookies.
- XSS (межсайтовый скриптинг) — внедрение вредного JS.
- SQL Injection (SQL‑инъекция) — подмена запроса к БД через ввод.
Самое важное (must‑know)
- CORS — это защита браузера, а не сервера.
Access-Control-Allow-Origin: *нельзя использовать сcredentials: true.- Preflight обязателен для
Authorizationиapplication/json. - OPTIONS должен возвращать разрешённые методы и заголовки.
- CSRF опасен, когда используются cookies.
- XSS чаще всего ворует токены из
localStorage. - SQL‑инъекция лечится параметризованными запросами/ORM.
1. Same‑Origin Policy — базовое ограничение браузера
Назначение: запретить скриптам доступ к чужим данным.
Простыми словами: браузер не даёт сайту читать чужое API без разрешения.
Аналогия: охранник пускает только сотрудников своего офиса.
Простыми словами: браузер не даёт сайту читать чужое API без разрешения.
Аналогия: охранник пускает только сотрудников своего офиса.
Пример:
https://app.com → https://api.app.com ❌ разные доменыhttps://app.com → https://app.com ✅ один origin🔎 Как это происходит на практике:
- Браузер сравнивает домен/протокол/порт.
- Если origin разные — включает защиту.
- Дальше требуется CORS‑разрешение.
Характеристики:
- ✅ работает только в браузере;
- ✅ защищает cookies и токены;
- ✅ не защищает сервер напрямую.
Когда использовать: всегда, это базовое правило браузера.
✅ Вывод: SOP — причина, почему нужен CORS.
✅ Вывод: SOP — причина, почему нужен CORS.
2. CORS — разрешение для нужных доменов
Назначение: безопасно разрешить доступ с других origin.
Простыми словами: сервер говорит браузеру «этому домену можно».
Аналогия: список гостей на входе.
Простыми словами: сервер говорит браузеру «этому домену можно».
Аналогия: список гостей на входе.
Пример:
HTTP/1.1 200 OKAccess-Control-Allow-Origin: https://frontend.comAccess-Control-Allow-Credentials: true🔎 Как это происходит на практике:
- Клиент делает запрос с заголовком
Origin. - Сервер проверяет origin и возвращает разрешение.
- Браузер либо пропускает запрос, либо блокирует.
Характеристики:
- ✅ управляется сервером;
- ✅ требует явного списка доменов;
- ✅
*нельзя при credentials.
Когда использовать: фронтенд и API на разных доменах.
✅ Вывод: CORS — это список «кому можно».
✅ Вывод: CORS — это список «кому можно».
3. Preflight (OPTIONS) — проверка перед запросом
Назначение: подтвердить, что сервер разрешает сложный запрос.
Простыми словами: браузер сначала спрашивает: «можно так?»
Аналогия: звонок охране перед визитом.
Простыми словами: браузер сначала спрашивает: «можно так?»
Аналогия: звонок охране перед визитом.
Пример:
OPTIONS /orders HTTP/1.1Origin: https://frontend.comAccess-Control-Request-Method: DELETEAccess-Control-Request-Headers: Authorization🔎 Как это происходит на практике:
- Браузер отправляет OPTIONS.
- Сервер отвечает разрешёнными методами и заголовками.
- Если всё ок — отправляется основной запрос.
Характеристики:
- ✅ нужен для
Authorizationиapplication/json; - ✅ кэшируется через
Access-Control-Max-Age; - ✅ ошибки preflight блокируют запрос.
Когда использовать: любые non‑simple запросы.
✅ Вывод: preflight — обязательная «проверка допуска».
✅ Вывод: preflight — обязательная «проверка допуска».
4. CSRF — атака через cookies
Назначение: предотвратить незаметные действия от имени пользователя.
Простыми словами: злоумышленник заставляет браузер отправить ваши cookies.
Аналогия: чужой человек подписывает документ вашей рукой.
Простыми словами: злоумышленник заставляет браузер отправить ваши cookies.
Аналогия: чужой человек подписывает документ вашей рукой.
Пример:
POST /transferCookie: session=abc123X-CSRF-Token: xyz789🔎 Как это происходит на практике:
- Пользователь залогинен, cookies активны.
- Злоумышленник отправляет запрос с другого сайта.
- Сервер проверяет CSRF‑токен и origin.
Характеристики:
- ✅ актуален только при cookies;
- ✅ защищается CSRF‑токеном и SameSite;
- ✅ не решается CORS‑заголовками.
Когда использовать: веб‑приложения с cookie‑сессиями.
✅ Вывод: CSRF — отдельная угроза, не путать с CORS.
✅ Вывод: CSRF — отдельная угроза, не путать с CORS.
5. XSS — внедрение вредного JavaScript
Назначение: не дать атакующему выполнить код в браузере пользователя.
Простыми словами: вредный скрипт крадёт токены или данные.
Аналогия: подслушивающий микрофон в вашем кабинете.
Простыми словами: вредный скрипт крадёт токены или данные.
Аналогия: подслушивающий микрофон в вашем кабинете.
Пример:
<!-- ❌ опасно --><div dangerouslySetInnerHTML={{ __html: userInput }}></div>🔎 Как это происходит на практике:
- Пользователь вводит комментарий с JS.
- Сервер хранит и отдаёт этот HTML.
- Скрипт исполняется и ворует токены.
Характеристики:
- ✅ лечится экранированием и санитизацией;
- ✅ CSP снижает риск;
- ✅ HttpOnly cookie защищает от кражи через JS.
Когда использовать: любые формы и пользовательский ввод.
✅ Вывод: XSS — главный враг токенов в браузере.
✅ Вывод: XSS — главный враг токенов в браузере.
6. SQL Injection — подмена запроса к БД
Назначение: защитить базу от подмены SQL.
Простыми словами: атакующий подставляет код вместо данных.
Аналогия: подмена письма с инструкцией кассиру.
Простыми словами: атакующий подставляет код вместо данных.
Аналогия: подмена письма с инструкцией кассиру.
Пример:
SELECT * FROM users WHERE email = $1🔎 Как это происходит на практике:
- Ввод пользователя попадает в запрос.
- Если строка склеивается — можно подставить SQL.
- Параметризация/ORM блокируют атаку.
Характеристики:
- ✅ лечится параметризованными запросами;
- ✅ ORM по умолчанию экранирует данные;
- ✅ валидация снижает риск.
Когда использовать: любые запросы в БД.
✅ Вывод: SQL‑инъекции лечатся только параметризацией.
✅ Вывод: SQL‑инъекции лечатся только параметризацией.
Сравнение: Simple vs Preflight
| Тип запроса | Когда | Что делает браузер |
|---|---|---|
| Simple | GET/POST/HEAD + простые headers | Сразу отправляет |
| Preflight | Authorization, JSON, PUT/DELETE | Сначала OPTIONS |
Сравнение: CORS vs CSRF vs XSS
| Тема | Что защищает | Где работает |
|---|---|---|
| CORS | доступ к API из браузера | браузер |
| CSRF | действия через cookies | сервер |
| XSS | выполнение JS в браузере | браузер |
Типичные ошибки
Ошибка 1: Access-Control-Allow-Origin: * при credentials
❌ Неправильно:
✅ Правильно: конкретный origin.
Почему: браузер блокирует комбинацию.
* и Allow-Credentials: true.✅ Правильно: конкретный origin.
Почему: браузер блокирует комбинацию.
Ошибка 2: Нет обработки OPTIONS
❌ Неправильно: сервер отвечает 404 на preflight.
✅ Правильно: вернуть разрешённые методы и headers.
Почему: без preflight запрос не дойдёт.
✅ Правильно: вернуть разрешённые методы и headers.
Почему: без preflight запрос не дойдёт.
Ошибка 3: Токены в localStorage
❌ Неправильно: хранить access token в localStorage.
✅ Правильно: HttpOnly cookie или безопасное хранилище.
Почему: XSS может украсть токен.
✅ Правильно: HttpOnly cookie или безопасное хранилище.
Почему: XSS может украсть токен.
Ошибка 4: Нет защиты от CSRF при cookies
❌ Неправильно: принимать POST без CSRF‑токена.
✅ Правильно: CSRF‑токен + SameSite.
Почему: cookies отправятся автоматически.
✅ Правильно: CSRF‑токен + SameSite.
Почему: cookies отправятся автоматически.
Ошибка 5: Склейка SQL‑строк
❌ Неправильно:
✅ Правильно: параметризованные запросы/ORM.
Почему: это прямой путь к SQL‑инъекции.
"... WHERE email = '" + email + "'".✅ Правильно: параметризованные запросы/ORM.
Почему: это прямой путь к SQL‑инъекции.
Ошибка 6: Без лимитов на запросы
❌ Неправильно: нет rate limit.
✅ Правильно: лимит по IP/ключу.
Почему: защита от brute‑force и DDoS.
✅ Правильно: лимит по IP/ключу.
Почему: защита от brute‑force и DDoS.
Best Practices
- Всегда HTTPS.
- Явный список origin + credentials при необходимости.
- Обрабатывайте OPTIONS и кэшируйте preflight.
- Для cookies включайте SameSite и CSRF‑токен.
- Экранируйте вывод и используйте CSP.
- Используйте ORM или параметризованные запросы.
- Включайте rate limiting и логирование.
Часто спрашивают на собеседованиях
- Чем CORS отличается от CSRF?
- Почему
Access-Control-Allow-Origin: *нельзя с credentials? - Когда браузер делает preflight?
- Как защищают токены от XSS?
- Почему SQL‑инъекции до сих пор опасны?
✅ Вывод: после этой лекции понятно, как разрешать доступ и защищать API.
Заключение
CORS отвечает за «кто может обращаться», security — за «как защититься».
✅ Вывод: настройте правила доступа и закройте типовые атаки.
✅ Вывод: настройте правила доступа и закройте типовые атаки.