🌐 CORS и SOP: Почему ваш браузер не доверяет чужим сайтам
Кратко: Same-Origin Policy (SOP) — это базовое правило безопасности браузера: сайт site.com не может читать данные с api.site.com, потому что это разные источники. А источник определяется протоколом, доменом и портом. CORS (Cross-Origin Resource Sharing) — это механизм, который позволяет серверу сознательно разрешить доступ к своим данным с других сайтов . Без CORS современный интернет с API и микросервисами был бы невозможен, а без SOP — небезопасен.
🧠 Same-Origin Policy: Почему браузер не доверяет чужим сайтам SOP — это политика безопасности, встроенная в браузер. Она запрещает скриптам с одного сайта читать данные с другого, если у них разные источники . Что считается разным источником? · Разные протоколы (http:// vs https://) · Разные домены (site.com vs api.site.com) · Разные порты (site.com:8080 vs site.com:443) Зачем это нужно? Если бы SOP не существовало, любой скрипт с вредоносного сайта мог бы читать ваши куки, переписку и данные из банковского приложения. Один клик по опасной ссылке — и всё, что у вас открыто во вкладках, становится доступно злоумышленнику . SOP — это не рекомендация, а обязательное правило, которое поддерживают все современные браузеры. Однако оно создаёт проблему: как разработчикам делать API и подключать сторонние сервисы?
🔧 CORS: Механизм, который разрешает доступ CORS (Cross-Origin Resource Sharing) — это стандарт, который позволяет серверу явно указать, какие сторонние источники могут получить доступ к его данным. Без CORS браузер просто заблокирует любой кросс-доменный запрос, даже если сервер готов его отдать . Процесс выглядит так: 1. Браузер отправляет запрос с заголовком Origin: https://my-site.com 2. Сервер отвечает с заголовком Access-Control-Allow-Origin: https://my-site.com 3. Браузер проверяет, совпадает ли Origin с разрешённым, и только тогда отдаёт данные скрипту Важно: Сервер не блокирует запросы. Он просто сообщает браузеру, разрешать ли скрипту читать ответ. Поэтому CORS защищает браузер, а не сервер. Если злоумышленник отправит запрос напрямую (через curl), CORS его не остановит.
⚠️ Типичные ошибки и уязвимости Ошибки в настройке CORS превращают защитный механизм в дыру. 1. Отражающийся Access-Control-Allow-Origin с Credentials: true Сервер подставляет в заголовок тот же Origin, который прислал клиент, и разрешает отправку кук. Злоумышленник создаёт свой сайт evil.com, жертва заходит на него, а скрипт отправляет запрос к уязвимому API. Сервер отражает evil.com в заголовке и разрешает чтение ответа. В результате хакер получает доступ к данным жертвы . Код уязвимости на бэкенде:
if (isset($_SERVER['HTTP_ORIGIN'])) { header("Access-Control-Allow-Origin: ".$_SERVER['HTTP_ORIGIN']); header('Access-Control-Allow-Credentials: true'); }
Теперь evil.com может читать любые данные с этого API через браузер жертвы . 2. Использование * с учётными данными Access-Control-Allow-Origin: * + Access-Control-Allow-Credentials: true — это нельзя делать. Браузер сам запретит такой запрос, но если разработчик неправильно настроил сервер, злоумышленники могут обойти проверку через null origin или поддомены . 3. Нестрогая проверка домена Если в коде проверка выглядит как if ($_SERVER['HTTP_ORIGIN'] == '*.site.com'), можно зарегистрировать домен fake-site.com и обойти защиту .
🛡️ Как защититься · Белый список источников на серверной стороне. Никогда не подставляйте Origin напрямую. Заведите список разрешённых доменов и проверяйте по нему . · Проверяйте домен целиком. Сравнивайте Origin со строкой, а не с подстрокой. · Ограничьте Access-Control-Allow-Credentials: true только для тех доменов, которым реально нужны куки. · Не допускайте null в Access-Control-Allow-Origin — его можно подставить через iframe с sandbox . Главный вывод: SOP защищает пользователя от чужих сайтов, а CORS позволяет разработчикам работать с API, но только в том случае, если настроен правильно. Ошибка в CORS сводит защиту на нет и открывает доступ к данным злоумышленникам. Проверяйте настройку CORS так же тщательно, как и пароли. #cors