Cross-Origin Resource Sharing (CORS) — чертовски сложная часть веб-разработки, особенно для начинающих. Большинство веб-разработчиков возятся с CORS не потому, что CORS сложен, а потому, что они не всегда работают с заголовками HTTP. Когда они сталкиваются лицом к лицу с HTTP-заголовками, они выживают за несколько часов поиска.
Итак, чтобы помочь следующему озадаченному веб-разработчику сэкономить время, я создал специальное руководство по основам CORS.

Понимание происхождения ресурсов

Прежде чем мы углубимся в CORS, важно изучить две ключевые концепции:

  1. Источник; и
  2. Политика одинакового происхождения (SOP).

Что такое происхождение?

Три вещи определяют происхождение веб-ресурса:

  1. Схема (протокол) — HTTP, HTTPS и т.д.
  2. Имя хоста (домен) — google.com, mammoth.io и т. д.
  3. Порт (если указан) — 8080, 3000 и т.д.

Два ресурса имеют одинаковое происхождение, если схема, имя хоста и порт совпадают. В следующей таблице объясняется, как это работает.

То же происхождение или перекрестное происхождение:

Теперь, кто определяет происхождение?

  • Это браузер (через адресную строку)?
  • Или веб-сервер, обслуживающий страницу?

Ответ — веб-сервер, который обслуживает основной запрос. То есть самый первый GET-запрос, сделанный браузером при вводе веб-URL. Следующая диаграмма является очень хорошим концептуальным представлением всего, что мы обсуждали до сих пор.

Пример приложения для социальных сетей

Предположим, у вас есть веб-сайт социальной сети — yoursocialnetweb.com. Пользователи могут войти в систему и обмениваться медиа/изображениями и т. д. с друзьями. Этот веб-сайт использует файлы cookie сеанса для аутентифицированного входа в систему. Когда пользователь решает отправить изображение, он инициирует запрос на yoursocialnetweb.com/share. Все идет нормально. Межсайтовый доступ к ресурсам может быть как необходимостью, так и риском. Вот как:

Доступ к ресурсам из разных источников — когда это необходимо

Теперь вы решили открыть доступ к API через api.yoursocialnetweb.com. Здесь, поскольку имя хоста отличается, браузер по умолчанию блокирует запросы. Чтобы включить эти запросы, вам необходимо разрешить запросы из этого источника.

Доступ к ресурсам из разных источников — когда есть риск

Расширяя тот же пример с социальными сетями, предположим, что вредоносный веб-сайт hack.yoursocialnetweb.com в другой вкладке браузера пытается инициировать запросы от имени пользователей. такие запросы будут проходить аутентификацию из-за файлов cookie сеанса. Любыми возможными способами вы предпочтете блокировать такие запросы.

Стандарты SOP и CORS

То, как ресурсы вашего приложения распределяются между разными источниками, представляет собой взаимодействие двух стандартных концепций:

  1. Политика одинакового происхождения (SOP) — реализуется стандартными браузерами.
  2. Заголовки Cross-Origin Resource Sharing (CORS) — указываются сервером приложений с использованием некоторых специальных заголовков HTTP.

Давайте разберемся в этих двух подробностях.

Стандарт СОП

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

SOP достигает этого, определяя набор правил доверия и недоверия для доступа к сети из разных источников. Эти правила со временем претерпели изменения с целью обеспечения некоторой стандартной и минимальной безопасности для доступа в Интернет при сохранении работоспособности существующих старых веб-сайтов.

Правила доверия/недоверия

  1. Перекрестное происхождение writes, такое как ссылки, перенаправления, отправка форм и т. д., разрешено. Если не заблокирован заголовками CORS. Это может вызвать проблемы CSRF (подделка межсайтовых запросов).
  2. Перекрестное происхождение reads запрещено.
  3. Доступ к другому источнику через встроенные элементы, такие как <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 (подделка межсайтовых запросов) с токенами, которые невозможно угадать. Но если вас интересуют эти вопросы, ознакомьтесь с приведенными ниже ссылками для получения подробных сведений.

Рекомендации