🪿 IT Птица · шпаргалка к собесу

CORS: Cross-Origin Resource Sharing

За 30 секунд
Same-Origin PolicyЧто такое originКто блокирует Простые vs сложныеPreflightЗаголовки Куки / credentialsКак чинитьCORS vs CSRF Подводные камниВопросы
1

Корень: Same-Origin Policy

CORS существует только потому, что есть SOP. Сначала — про неё.

Браузер по умолчанию не даёт скрипту читать ответы с другого источника — чтобы зловредный сайт не сходил от твоего имени (с твоими куками) в твою почту/банк и не прочитал данные. Это Same-Origin Policy. CORS — это контролируемое ослабление SOP: сервер явно говорит «этому origin читать можно».

❌ SOP блокирует (чтение)
  • fetch / XHR — JS не прочитает ответ cross-origin
  • чтение чужого iframe DOM
✅ SOP разрешает (отправка/встраивание)
  • <img>, <script src>, <link>
  • отправка <form> на чужой домен
  • встраивание <iframe> (без чтения)
Ключевое: SOP запрещает прочитать ответ, но не запрещает отправить запрос. Поэтому одних CORS мало против CSRF (см. §9).
2

Что такое origin

Origin = схема + хост + порт. Совпасть должны все три.

URL запроса (из https://site.com)Same-origin?
https://site.com/api✅ да
http://site.com (другая схема)❌ нет
https://api.site.com (поддомен)❌ нет
https://site.com:8443 (другой порт)❌ нет
Поддомен — это другой origin. «site.com и api.site.com — это CORS» — да.
3

Кто блокирует и кого защищает

Любимый вопрос «кто инициатор ошибки CORS».

Блокирует — браузер

Сервер часто получает запрос и обрабатывает. Браузер просто не отдаёт ответ скрипту, если нет нужных заголовков. Ошибка — на клиенте.

Решает — сервер

Разрешение даёт сервер заголовками Access-Control-*. Фронт «пофиксить CORS у себя» не может — только сервер или прокси.

CORS — не защита сервера. Это правило браузера. curl, Postman, сервер-к-серверу его игнорируют. Защищает он пользователя в браузере, а не API от хакера.
4

Простые vs сложные запросы

От этого зависит, будет ли preflight.

✅ Простой (без preflight)
  • метод GET, POST или HEAD
  • только «безопасные» заголовки
  • Content-Type: text/plain, multipart/form-data или x-www-form-urlencoded
⚠️ Сложный (с preflight)
  • метод PUT/DELETE/PATCH
  • кастомный заголовок (Authorization* , X-…)
  • Content-Type: application/json
Почти любой реальный API-запрос (JSON + токен) — сложный → идёт preflight. Поэтому в DevTools видишь «лишний» OPTIONS.
5

Preflight: предварительный OPTIONS

Браузер сам спрашивает у сервера разрешение ДО основного запроса.

Браузер шлёт OPTIONSс Origin, Access-Control-Request-Method, Access-Control-Request-Headers
Сервер отвечает разрешениемAllow-Origin, Allow-Methods, Allow-Headers, Max-Age
Если ок — идёт реальный запросесли нет — основной запрос вообще не отправляется, ошибка CORS
OPTIONS /api/user            Ответ сервера:
Origin: https://site.com     Access-Control-Allow-Origin: https://site.com
Access-Control-Request-      Access-Control-Allow-Methods: PUT, GET
  Method: PUT                Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Request-      Access-Control-Max-Age: 600
  Headers: authorization
Access-Control-Max-Age кэширует preflight (в секундах) → браузер не шлёт OPTIONS на каждый запрос. Так «обходят лишний OPTIONS».
6

Заголовки CORS

Что шлёт браузер и чем отвечает сервер.

Заголовок (ответ сервера)Что значит
Access-Control-Allow-Originкому можно: конкретный origin или *
Access-Control-Allow-Methodsразрешённые методы (для preflight)
Access-Control-Allow-Headersразрешённые кастомные заголовки
Access-Control-Allow-Credentialstrue → можно слать куки
Access-Control-Expose-Headersкакие заголовки ответа JS может прочитать
Access-Control-Max-Ageсколько секунд кэшировать preflight
Со стороны браузера запрос всегда несёт Origin, а в preflight ещё Access-Control-Request-Method/Headers.
7

Куки и credentials

Самое узкое место — когда нужно слать сессионные куки cross-origin.

По умолчанию fetch не шлёт куки на другой origin. Чтобы слать: fetch(url, { credentials: 'include' }) (или xhr.withCredentials = true).

Жёсткие правила при credentials:
Allow-Origin не может быть * — только конкретный origin.
Allow-Credentials: true обязателен.
Allow-Headers/Allow-Methods тоже не *.
• Сама кука должна быть SameSite=None; Secure, иначе браузер её не отправит cross-site.
8

Как чинят CORS на практике

СпособКогда
Настроить заголовки на сервере/APIправильный путь (prod)
Dev-прокси (Vite server.proxy, webpack devServer)локальная разработка — браузер думает, что same-origin
Серверный прокси / BFFфронт ходит на свой бэкенд, тот — на чужой API (server-to-server без CORS)
Reverse-proxy (nginx) добавляет заголовкикогда нет доступа к коду API
«Отключить CORS в браузере» / расширения — только для отладки, не решение. JSONP — устаревший хак (только GET).
9

CORS vs CSRF (не путать)

Связка из реальных собесов (РСХБ ИНТЕХ: «CORS, CSRF, защита от CSRF»).

CORS

Про чтение чужого ответа из JS. Ослабляет SOP. Защищает данные пользователя от чужого скрипта.

CSRF

Атака: чужой сайт отправляет запрос от твоего имени (куки прикрепятся сами). CORS тут не спасает — простую форму можно слать без preflight.

От CSRF защищают: SameSite=Lax/Strict у кук + CSRF-токен (сервер проверяет секрет, которого чужой сайт не знает). Не CORS.
10

Подводные камни

❌ Частые заблуждения
  • «CORS чинят на фронте» — нет, на сервере/прокси
  • «CORS защищает API» — нет, это правило браузера
  • «Ошибка CORS = запрос не дошёл» — простой мог дойти, не прочитан ответ
  • * + credentials вместе — запрещено
  • забыть обработать OPTIONS на сервере
✅ Как правильно
  • Разрешения — заголовки сервера
  • CORS = защита пользователя, не сервера
  • Сложный запрос с preflight не дойдёт, если OPTIONS не прошёл
  • С куками — конкретный origin + Allow-Credentials
  • Сервер отвечает на preflight OPTIONS
11

Реальные вопросы с собесов

Из нашей базы 2000+ собесов.

• Что такое CORS, зачем нужен? — Сбер, OCS Distribution, Digital Biz Factory, Цифровая мануфактура
• CORS, preflight (OPTIONS) — что это, как работает — Техно Диасофт, BRAINSHELL, АГ-Логистика
• Кто инициатор ошибки CORS? — Sminex
• CORS и поддомены, заголовки — АФЛТ Системс
• Как «обойти» CORS — МоеVideo
• CORS + CSRF, способы защиты от CSRF — РСХБ ИНТЕХ
• CSRF-атаки, CSRF-токен — для чего — WMT, Согаз, Сбер

Каверзные follow-up

Кто блокирует запрос при CORS-ошибке?
Браузер, на стороне клиента. Сервер запрос мог получить.
Можно ли пофиксить CORS только на фронте?
Нет — заголовки даёт сервер; в dev спасает прокси.
site.com и api.site.com — это CORS?
Да, поддомен — другой origin.
Почему с куками нельзя Allow-Origin: *?
Безопасность: с credentials origin должен быть конкретным.
CORS защищает от CSRF?
Нет. От CSRF — SameSite-куки + CSRF-токен.
Почему перед PUT летит OPTIONS?
Это preflight для «сложного» запроса.
12

Граничит с темами

Веб-безопасность: XSS · CSRF вглубь · CSP (Content-Security-Policy) · cookie-флаги (HttpOnly/Secure/SameSite) · аутентификация vs авторизация (JWT, сессии) — берём отдельно по запросу.