Обмен ресурсами между источниками - это механизм, позволяющий веб-странице отправлять запросы XMLHttp в другой домен (из Википедии ).
Последние пару дней я возился с CORS и думаю, что у меня довольно хорошее понимание того, как все работает.
Так что мой вопрос не о том, как работает CORS / preflight, а о причине, по которой я выбрал preflights в качестве нового типа запроса . Я не вижу никакой причины, по которой серверу A необходимо отправлять предварительную проверку (PR) на сервер B, чтобы выяснить, будет ли принят реальный запрос (RR) или нет - B, безусловно, сможет принять / отклонить RR без любой предыдущий пиар.
После долгих поисков я нашел эту информацию на сайте www.w3.org (7.1.5):
Чтобы защитить ресурсы от запросов перекрестного происхождения, которые не могли быть отправлены определенными пользовательскими агентами до того, как эта спецификация существовала, делается предварительный запрос, чтобы гарантировать, что ресурс осведомлен об этой спецификации.
Я считаю, что это самое трудное для понимания предложение. Моя интерпретация (лучше назвать это «предположение») заключается в том, что речь идет о защите сервера B от запросов от сервера C, который не знает о спецификации.
Может кто-нибудь объяснить сценарий / показать проблему, которую PR + RR решает лучше, чем один RR?
Какова была мотивация введения предварительных запросов?
Предварительные запросы были введены так, чтобы браузер мог быть уверен, что он имеет дело с сервером, поддерживающим CORS, перед отправкой определенных запросов. Эти запросы были определены как потенциально опасные (с изменением состояния) и новые (невозможные до CORS из-за единой политики происхождения ). Использование запросов предварительной проверки означает, что серверы должны подписаться (путем правильного ответа на предварительную проверку) на новые, потенциально опасные типы запросов, которые CORS делает возможным.
В этом смысл этой части спецификации : «Для защиты ресурсов от запросов разных источников, которые не могли быть отправлены определенными пользовательскими агентами до того, как эта спецификация существовала, делается предварительный запрос, чтобы гарантировать, что ресурс осведомлен об этой спецификации».
Можете ли вы дать мне пример?
Давайте представим, что пользователь браузера вошел на свой банковский сайт по адресу
A.com
. Когда они переходят к вредоносным программамB.com
, эта страница содержит некоторый Javascript, который пытается отправитьDELETE
запросA.com/account
. Поскольку пользователь вошел в системуA.com
, этот запрос, если он будет отправлен, будет включать файлы cookie, которые идентифицируют пользователя.До CORS браузер Same Policy Policy блокировал бы его от отправки этого запроса. Но так как целью CORS является сделать возможным только такой тип связи между источниками, это больше не подходит.
Браузер может просто отправить
DELETE
и позволить серверу решить, как его обработать. Но что, еслиA.com
не знает протокол CORS? Это может пойти дальше и выполнить опасноеDELETE
. Можно было бы предположить, что - из-за одинаковой политики происхождения браузера - он никогда не мог получить такой запрос, и, таким образом, он никогда не был защищен от такой атаки.Для защиты таких серверов, не поддерживающих CORS, протокол требует, чтобы браузер сначала отправил предварительный запрос . Этот новый тип запроса - это то, на что только серверы, поддерживающие CORS, могут отвечать должным образом, позволяя браузеру узнать, безопасно ли отправлять фактическое сообщение
DELETE
.Почему весь этот шум вокруг браузера, не может ли злоумышленник просто отправить
DELETE
запрос со своего компьютера?Конечно, но такой запрос не будет включать куки пользователя. Предназначенная для предотвращения атаки атака основана на том факте, что браузер будет отправлять файлы cookie (в частности, информацию об аутентификации для пользователя) для другого домена вместе с запросом.
Это звучит , как Cross-Site Request Подделка , где форма на сайте
B.com
банке ,POST
чтобыA.com
с печеньем пользователя и нанести ущерб.Вот так. Это можно сделать так, что предварительные запросы были созданы таким образом, чтобы не увеличивать поверхность атаки CSRF для серверов, не поддерживающих CORS.
Но, глядя на требования к «простым» запросам, которые не требуют предварительных проверок, я вижу, что
POST
это все еще разрешено. Это может изменить состояние и удалить данные, какDELETE
!Это правда! CORS не защищает ваш сайт от CSRF-атак. Опять же, без CORS вы также не защищены от CSRF-атак. Цель предварительных запросов - ограничить воздействие CSRF на то, что уже существовало в мире до CORS.
Вздох. ОК, я неохотно принимаю необходимость предварительных запросов. Но почему мы должны делать это для каждого ресурса (URL) на сервере? Сервер либо обрабатывает CORS, либо нет.
Вы уверены, что? Многочисленные серверы нередко обрабатывают запросы для одного домена. Например, это может быть случай, когда запросы
A.com/url1
обрабатываются одним видом сервера, а запросыA.com/url2
обрабатываются другим типом сервера. Как правило, сервер, обрабатывающий один ресурс, не может гарантировать безопасность всех ресурсов в этом домене.Хорошо. Давай пойдем на компромисс. Давайте создадим новый заголовок CORS, который позволит серверу точно указывать, за какие ресурсы он может говорить, чтобы избежать дополнительных предварительных запросов к этим URL-адресам.
Хорошая идея! На самом деле, заголовок
Access-Control-Policy-Path
был предложен именно для этой цели. В конечном счете, однако, это было исключено из спецификации, по- видимому, потому что некоторые серверы неправильно реализовали спецификацию URI таким образом, что запросы к путям, которые казались безопасными для браузера, на самом деле не были бы безопасны на сломанных серверах.Было ли это разумным решением, которое отдавало приоритет безопасности над производительностью, позволяя браузерам немедленно внедрять спецификацию CORS, не подвергая риску существующие серверы? Или было недальновидно обречь интернет на потерю пропускной способности и удвоить задержку, просто чтобы учесть ошибки на конкретном сервере в определенное время?
Мнения расходятся.
Ну, по крайней мере, браузеры будут кэшировать предпечатную проверку для одного URL?
Да. Хотя, вероятно, не очень долго. В браузерах WebKit максимальное время кеширования перед полетом в настоящее время составляет 10 минут .
Вздох. Что ж, если я знаю, что мои серверы поддерживают CORS и, следовательно, не нуждаются в защите, предоставляемой предварительными запросами, есть ли способ избежать их?
Ваш единственный реальный вариант - убедиться, что вы соответствуете требованиям «простых» запросов. Это может означать исключение пользовательских заголовков, которые вы в противном случае включили бы (например
X-Requested-With
), ложь оContent-Type
или больше.Что бы вы ни делали, вы должны убедиться в наличии надлежащих средств защиты CSRF, поскольку в спецификации CORS не рассматриваются отклонения «простых» запросов, в том числе небезопасных
POST
. Как сказано в спецификации : «ресурсы, для которых простые запросы имеют значение, отличное от извлечения, должны защищать себя от подделки межсайтовых запросов».источник
Рассмотрим мир междоменных запросов до CORS. Вы можете сделать стандартную форму POST или использовать тег
script
илиimage
для выдачи запроса GET. Вы не могли сделать какой-либо другой тип запроса, кроме GET / POST, и не могли выдавать пользовательские заголовки для этих запросов.С появлением CORS авторы спецификаций столкнулись с проблемой внедрения нового междоменного механизма без нарушения существующей семантики сети. Они решили сделать это, предоставив серверам возможность подписаться на любой новый тип запроса. Это согласие является предварительным запросом.
Таким образом, запросы GET / POST без каких-либо пользовательских заголовков не нуждаются в предварительной проверке, поскольку эти запросы уже были возможны до CORS. Но любой запрос с помощью пользовательских заголовков или PUT / DELETE запросов, действительно нужен предполетный, так как они являются новыми для CORS спецификации. Если сервер ничего не знает о CORS, он ответит без заголовков, специфичных для CORS, и фактический запрос не будет выполнен.
Без предварительного запроса серверы могут начать видеть неожиданные запросы от браузеров. Это может привести к проблеме безопасности, если серверы не будут подготовлены к этим типам запросов. Предварительная проверка CORS позволяет междоменным запросам безопасно вводиться в Интернет.
источник
CORS позволяет вам указать больше заголовков и типов методов, чем это было возможно ранее при использовании кросс-источника
<img src>
или<form action>
.Некоторые серверы могли быть (плохо) защищены из-за предположения, что браузер не может сделать, например,
DELETE
запрос перекрестного происхождения или запрос перекрестного происхождения сX-Requested-With
заголовком, поэтому такие запросы являются «доверенными».Чтобы убедиться, что сервер действительно-действительно поддерживает CORS, а не просто отвечает на случайные запросы, выполняется предварительная проверка.
источник
Вот еще один способ посмотреть на это, используя код:
До появления CORS попытка эксплойта, описанная выше, потерпела бы неудачу, поскольку она нарушает политику того же происхождения. Разработанный таким образом API не нуждался в защите XSRF, потому что он был защищен собственной моделью безопасности браузера. Браузер до CORS не мог сгенерировать JSON POST с несколькими источниками.
Теперь на сцену выходит CORS - если не требуется вход в CORS перед полетом, внезапно этот сайт будет иметь огромную уязвимость не по своей вине.
Чтобы объяснить, почему некоторым запросам разрешено пропускать предполёт, на это отвечает спецификация:
Чтобы распутать это, GET предварительно не пролетает, потому что это «простой метод», как определено в 7.1.5. (Заголовки также должны быть «простыми», чтобы избежать предполетной подготовки). Обоснованием этого является то, что «простой» перекрестный GET-запрос уже может быть выполнен, например,
<script src="">
(так работает JSONP). Поскольку любой элемент сsrc
атрибутом может инициировать GET перекрестного происхождения без предварительной проверки, не было бы никакой выгоды в плане безопасности, требующей предварительного боя на «простых» XHR.источник
Я чувствую, что другие ответы не фокусируются на причине, что предварительный бой повышает безопасность.
Сценарии:
1) С предполетным полетом . Злоумышленник подделывает запрос с сайта dummy-forums.com, пока пользователь проходит аутентификацию на safe-bank.com.
Если Сервер не проверяет источник и каким-то образом имеет изъян, браузер выдаст запрос перед полетом, OPTION метод. Сервер не знает ни одного из этих CORS, которые браузер ожидает в качестве ответа, поэтому браузер не будет работать (никакого вреда вообще).
2) Без предполетной подготовки . Злоумышленник подделывает запрос в соответствии с тем же сценарием, что и выше, браузер сразу же отправляет запрос POST или PUT, сервер принимает его и может обработать, что может нанести некоторый вред.
Если злоумышленник отправляет запрос напрямую, из разных источников, с какого-то случайного хоста, скорее всего, он думает о запросе без аутентификации. Это поддельный запрос, но не запрос xsrf. поэтому сервер проверит учетные данные и потерпит неудачу. CORS не пытается помешать атакующему, имеющему учетные данные, выдавать запросы, хотя белый список может помочь уменьшить этот вектор атаки.
Предполетный механизм добавляет безопасность и согласованность между клиентами и серверами. Я не знаю, стоит ли это дополнительного рукопожатия для каждого запроса, поскольку кэширование там очень полезно, но вот как это работает.
источник
Источник
источник
Предполетные запросы необходимы для запросов, которые могут изменить состояние на сервере. Есть 2 типа запросов -
1) Вызовы, которые не могут изменить состояние на сервере (например, GET) - пользователь может получить ответ на запрос (если сервер не проверяет источник), но если запрашивающий домен не добавлен в заголовок ответа Access-Control- Allow-Origin, браузер не показывает данные пользователю, т. Е. Запрос отправляется из браузера, но пользователь не может просмотреть / использовать ответ.
2) Вызовы, которые могут изменить состояние на сервере (например, POST, DELETE) - поскольку в 1), мы видим, что браузер не блокирует запрос, но ответ, вызовы с изменением состояния не должны быть разрешены без предварительной проверки. , Такие вызовы могут вносить изменения в доверяющий сервер, который не проверяет происхождение вызовов (так называемая подделка межсайтовых запросов), даже если ответ на запрос браузера может быть ошибочным. По этой причине у нас есть концепция предполетных запросов, которые делают вызов OPTIONS, прежде чем любые вызовы, изменяющие состояние, могут быть отправлены на сервер.
источник
Разве заранее не просят о производительности ? С помощью предварительно выданных запросов клиент может быстро узнать, разрешена ли операция, прежде чем отправлять большой объем данных, например, в JSON с методом PUT. Или перед перемещением конфиденциальных данных в заголовках аутентификации по проводам.
Факт PUT, DELETE и других методов, кроме пользовательских заголовков, по умолчанию не разрешен (им нужно явное разрешение с помощью «Access-Control-Request-Methods» и «Access-Control-Request-Headers»), что звучит точно так же, как двойная проверка, потому что эти операции могут иметь больше последствий для пользовательских данных, а не GET-запросов. Итак, это звучит как:
«Я видел, что вы разрешаете межсайтовые запросы с http: //foo.example , НО ВЫ УВЕРЕНЫ, что разрешите УДАЛИТЬ запросы? Рассматривали ли вы влияние, которое эти запросы могут оказать на пользовательские данные?»
Я не понял цитируемой корреляции между предварительно выданными запросами и преимуществами старых серверов. Веб-служба, которая была реализована до CORS или без поддержки CORS, никогда не получит ЛЮБОЙ межсайтовый запрос, потому что сначала их ответ не будет иметь заголовка «Access-Control-Allow-Origin».
источник
В браузере, поддерживающем CORS, запросы на чтение (например, GET) уже защищены политикой того же происхождения: вредоносный веб-сайт, пытающийся сделать аутентифицированный междоменный запрос (например, на веб-сайт интернет-банка жертвы или интерфейс конфигурации маршрутизатора), не будет быть в состоянии прочитать возвращенные данные, потому что банк или маршрутизатор не устанавливают
Access-Control-Allow-Origin
заголовок.Однако при написании запросов (например, POST) повреждение наносится, когда запрос поступает на веб-сервер. * Веб-сервер может проверить
Origin
заголовок, чтобы определить, является ли запрос допустимым, но эта проверка часто не выполняется, поскольку веб-серверу нет необходимости. для CORS или веб-сервера старше, чем CORS, и поэтому он предполагает, что междоменные POST полностью запрещены политикой того же происхождения.Вот почему веб-серверам предоставляется возможность получать междоменные запросы на запись .
* По сути AJAX-версия CSRF.
источник