Cross-Origin Resource Sharing (CORS) — чертовски сложная часть веб-разработки, особенно для начинающих. Большинство веб-разработчиков возятся с CORS не потому, что CORS сложен, а потому, что они не всегда работают с заголовками HTTP. Когда они сталкиваются лицом к лицу с HTTP-заголовками, они выживают за несколько часов поиска.
Итак, чтобы помочь следующему озадаченному веб-разработчику сэкономить время, я создал специальное руководство по основам CORS.
Понимание происхождения ресурсов
Прежде чем мы углубимся в CORS, важно изучить две ключевые концепции:
- Источник; и
- Политика одинакового происхождения (SOP).
Что такое происхождение?
Три вещи определяют происхождение веб-ресурса:
- Схема (протокол) — HTTP, HTTPS и т.д.
- Имя хоста (домен) — google.com, mammoth.io и т. д.
- Порт (если указан) — 8080, 3000 и т.д.
Два ресурса имеют одинаковое происхождение, если схема, имя хоста и порт совпадают. В следующей таблице объясняется, как это работает.
То же происхождение или перекрестное происхождение:
Теперь, кто определяет происхождение?
- Это браузер (через адресную строку)?
- Или веб-сервер, обслуживающий страницу?
Ответ — веб-сервер, который обслуживает основной запрос. То есть самый первый GET-запрос, сделанный браузером при вводе веб-URL. Следующая диаграмма является очень хорошим концептуальным представлением всего, что мы обсуждали до сих пор.
Пример приложения для социальных сетей
Предположим, у вас есть веб-сайт социальной сети — yoursocialnetweb.com. Пользователи могут войти в систему и обмениваться медиа/изображениями и т. д. с друзьями. Этот веб-сайт использует файлы cookie сеанса для аутентифицированного входа в систему. Когда пользователь решает отправить изображение, он инициирует запрос на yoursocialnetweb.com/share. Все идет нормально. Межсайтовый доступ к ресурсам может быть как необходимостью, так и риском. Вот как:
Доступ к ресурсам из разных источников — когда это необходимо
Теперь вы решили открыть доступ к API через api.yoursocialnetweb.com
. Здесь, поскольку имя хоста отличается, браузер по умолчанию блокирует запросы. Чтобы включить эти запросы, вам необходимо разрешить запросы из этого источника.
Доступ к ресурсам из разных источников — когда есть риск
Расширяя тот же пример с социальными сетями, предположим, что вредоносный веб-сайт hack.yoursocialnetweb.com
в другой вкладке браузера пытается инициировать запросы от имени пользователей. такие запросы будут проходить аутентификацию из-за файлов cookie сеанса. Любыми возможными способами вы предпочтете блокировать такие запросы.
Стандарты SOP и CORS
То, как ресурсы вашего приложения распределяются между разными источниками, представляет собой взаимодействие двух стандартных концепций:
- Политика одинакового происхождения (SOP) — реализуется стандартными браузерами.
- Заголовки Cross-Origin Resource Sharing (CORS) — указываются сервером приложений с использованием некоторых специальных заголовков HTTP.
Давайте разберемся в этих двух подробностях.
Стандарт СОП
Вообще говоря, в соответствии с SOP документы и сценарии, полученные из разных источников, изолированы друг от друга, они функционируют в своем изолированном контексте безопасности. Цель здесь состоит в том, чтобы позволить пользователям посещать ненадежные веб-сайты, чтобы эти веб-сайты не мешали сеансу пользователя с честными веб-сайтами.
SOP достигает этого, определяя набор правил доверия и недоверия для доступа к сети из разных источников. Эти правила со временем претерпели изменения с целью обеспечения некоторой стандартной и минимальной безопасности для доступа в Интернет при сохранении работоспособности существующих старых веб-сайтов.
Правила доверия/недоверия
- Перекрестное происхождение
writes
, такое как ссылки, перенаправления, отправка форм и т. д., разрешено. Если не заблокирован заголовками CORS. Это может вызвать проблемы CSRF (подделка межсайтовых запросов). - Перекрестное происхождение
reads
запрещено. - Доступ к другому источнику через встроенные элементы, такие как
<script src="…"></script>
,<link rel="stylesheet" href="…">
,<iframe>
, медиафайлы и т. д., разрешен. если это проблема безопасности, сделайте свой ресурс не встраиваемым.
Стандарт КОРС
Теперь давайте будем более формальными с Обмен ресурсами между источниками (CORS).
Это механизм на основе HTTP-заголовков, который позволяет серверу, обслуживающему ресурсы из разных источников, указывать, из каких источников браузеры должны разрешать загрузку ресурсов.
Эти заголовки позволяют разработчику указать, чему следует доверять, а чему нет. Браузер действует как доверенный объект между javascript (выполнение вызовов API) и удаленным сервером. Для вызовов API из разных источников браузер добавляет заголовок Origin
в запрос и ожидает, что удаленный сервер отправит заголовок access-control-allow-origin
в ответе. Если удаленный сервер разрешает источник запроса, браузер отправляет ответ на код javascript, в противном случае он отклоняет HTTP-запрос с сообщением об ошибке CORS. Следующая диаграмма объясняет это.
SOP и CORS как две стороны одной медали
И SOP, и CORS говорят о правилах доступа к ресурсам. То, что реализуется всеми стандартными браузерами, называется «SOP», а то, что передается браузеру удаленным сервером, называется «CORS».
Часто задают вопрос: если SOP и CORS реализованы в браузере, значит ли это, что все подобные проблемы безопасности являются обоснованными, если кто-то использует специально созданные или нестандартные браузеры? или получить доступ к API программно?
Ответ: Да. В противном случае это остается серьезной проблемой безопасности. Существует гораздо больше рисков безопасности и соответствующих решений, связанных с защитой веб-приложения.
Механика CORS — предварительные запросы
Всякий раз, когда делается HTTP-запрос из разных источников, браузер сначала проверяет разрешение на удаленном сервере, прежде чем выполнять вызов API. Эта проверка разрешений называется preflight request
.
Предпечатный запрос — это запрос HTTP OPTIONS, состоящий из 3 заголовков:
Origin
Access-Control-Request-Method
: фактический HTTP-метод текущего запроса (GET, POST, DELETE etc)
Access-Control-Request-Headers
: разделенный запятыми список небезопасных HTTP-заголовков текущего запроса. например настраиваемые заголовки, такие как X-ACCOUNT-ID и т. д.
В ответ на предварительный запрос удаленный сервер отвечает набором заголовков, чтобы помочь браузеру решить, следует ли выполнять фактический HTTP-вызов.
Заголовки ответа перед отправкой
Дополнительная информация
Если вы новичок в теме CORS, вы можете пропустить этот раздел. некоторые важные полезные моменты, которые мы рассмотрим здесь.
Изменение происхождения
Можно (не рекомендуется) изменить источник, установив document.domain
в супердомен. Но это имеет ограничения на практике (поэтому не рекомендуется). Таким образом, для практических целей невозможно установить или переопределить «источник» для HTTP-запроса. Это устанавливается браузером динамически.
Наследование происхождения
Если в URL-адресах, таких как
about:blank
, отсутствует информация об исходном сервере, то исполняемые сценарии наследуют ее от родительского сценария, если таковые имеются.
Дополнительные заголовки CORS
Access-Control-Allow-Credentials
Если вы хотите, чтобы браузер отправлял безопасные файлы cookie вместе с HTTP-запросами, этот заголовок должен быть установлен.
Примечание: Access-Control-Allow-Origin
запрещено использовать звездочку *
для запросов с учетными данными, он должен указать там точное происхождение. Это дополнительная мера безопасности, гарантирующая, что сервер доверяет таким запросам.
Access-Control-Expose-Headers
По умолчанию клиентским сценариям в ответе CORS предоставляется только набор стандартных заголовков, которые называются «безопасными заголовками» или «заголовками из безопасного списка CORS». Дополнительные заголовки, в том числе пользовательские заголовки, можно добавить в список надежных отправителей с помощью Access-Control-Expose-Headers
. Значение здесь должно быть списком заголовков, разделенных запятыми. Например,
Access-Control-Expose-Headers: X-Custom-Header, X-API-KEY
Не следует путать с Access-Control-Allow-Headers
. Могут быть заголовки, которые разрешены, но программно не доступны клиентским скриптам.
Краткое содержание
Надеемся, что в этой статье объяснено несколько основных концепций управления доступом к ресурсам из разных источников и прочная концептуальная основа по вопросам, связанным с CORS. В интересах краткости и простоты я решил опустить некоторые из более тонких, но интересных деталей, таких как критерий принятия решения для предварительного запроса или как смягчить проблемы CSRF (подделка межсайтовых запросов) с токенами, которые невозможно угадать. Но если вас интересуют эти вопросы, ознакомьтесь с приведенными ниже ссылками для получения подробных сведений.
Рекомендации
- Совместное использование ресурсов между источниками (CORS) — HTTP | МДН
- Политика единого происхождения — Веб-безопасность | МДН
- Политика того же происхождения (SOP) | Академия веб-безопасности
- Единая политика происхождения — веб-безопасность
- Политика того же происхождения
- Выбрать стандарт
- Access-Control-Allow-Headers — HTTP | МДН
- Access-Control-Expose-Headers — HTTP | МДН
- Заголовки ответов CORS-безопасного списка| МДН