2012-02-10 3 views
28

XMLHttpRequest s требует, чтобы CORS работал в междоменном пространстве. Аналогично для веб-шрифтов, текстур WebGL и некоторых других вещей. В общем, все новые API, похоже, имеют это ограничение.Почему API-интерфейсы браузера ограничивают междоменные запросы?

Почему?

Это настолько легко обойти: все, что требуется, это простой серверный прокси-сервер. Другими словами, серверный код не запрещается выполнять междоменные запросы; почему клиентский код? Как это дает какую-либо безопасность, кому-либо?

И это так непоследовательно: Я не могу XMLHttpRequest, но я могу <script src> или <link rel> или <img src> или . Что же ограничивает XHR и т. Д.?

ответ

50

Если я посетить вредоносный веб-сайт, я хочу быть уверен, что:

  1. Он не может читать мои личные данные с других веб-сайтов, которые я использую. Think attacker.com, читающий gmail.com
  2. Он не может выполнять действия от моего имени на других сайтах, которые я использую. Подумайте, как атаковать злоумышленник, перечислив средства со своего счета на bank.com.

Same Origin Policy решает первую проблему. Вторая проблема называется подделкой запроса на перекрестный сайт и не может быть решена с помощью существующих междоменных ограничений.

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

  • Правило 1: Не давайте вы читали что-нибудь из другого домена
  • Правило 2: Позволяет писать все, что вы хотите другой домен, но правило № 1 не позволит вам прочитать ответ.
  • Правило 3: Вы можете свободно делать запросы GET междоменные и запросы POST, но вы не можете контролировать HTTP-заголовки

Давайте посмотрим, как различные вещи, которые вы перечислили линии до вышеуказанных правил:

  1. <img> теги позволяют делать HTTP-запрос, но нет возможности прочитать содержимое изображения, кроме простого его отображения. Например, если я сделаю это <img src="http://bank.com/get/latest/funds"/>, запрос будет проходить (правило 2). Но нападающий не может видеть мой баланс (правило 1).

  2. <script> теги работают в основном как <img>. Если вы сделаете что-то вроде <script src="http://bank.com/get/latest/funds">, запрос будет проходить. Браузер также попытается проанализировать ответ как JavaScript, и он потерпит неудачу.

  3. Существует известное злоупотребление знаками <script> под названием JSONP, где вы вступаете в сговор с междоменным сервером, чтобы вы могли «читать» кросс-домен. Но без явного участия сервера междоменного, вы не можете прочитать ответ через <script> тег

  4. <link> для таблиц стилей работать в основном как <script> теги, за исключением того, ответ оценивается как CSS. В общем, вы не можете прочитать ответ - если ответ каким-то образом не будет правильно сформированным CSS.

  5. - это, по сути, новое окно браузера. Вы не можете прочитать HTML-код междоменного iframe. Кстати, вы можете изменить URL-адрес междоменного iframe, но вы не можете прочитать URL-адрес. Обратите внимание, как это следует из двух правил, упомянутых выше.

  6. XMLHttpRequest - самый универсальный способ для обработки HTTP-запросов. Это полностью находится в управлении разработчиками; браузер не делает ничего с ответом. Например, в случае <img>, <script> или <link>, браузер принимает определенный формат и, в целом, проверяет его соответствующим образом. Но в XHR нет предписанного формата ответа. Таким образом, браузеры применяют одну и ту же политику происхождения и не позволяют вам прочитать ответ, если веб-сайт перекрестного домена явно не позволяет вам.

  7. Шрифты через font-face являются аномалией. AFAIK, только для Firefox требуется поведение при входе; другие браузеры позволяют использовать шрифты так же, как вы использовали бы изображения.

Короче говоря, такая же политика происхождения согласована. Если вы найдете способ сделать кросс-доменный запрос и, прочитайте ответ без явного разрешения на междоменном веб-сайте - вы сделаете заголовки по всему миру.

EDIT: Почему я не могу обойти все это с помощью прокси-сервера на стороне сервера?

Чтобы gmail отображал персонализированные данные, ему нужны куки-файлы из вашего браузера. Некоторые сайты используют базовую аутентификацию HTTP, в которой учетные данные хранятся в браузере.

Прокси-сервер на стороне сервера не может получить доступ к файлам cookie или базовым учетным данным. И поэтому, даже если он может сделать запрос, сервер не будет возвращать данные, специфичные для пользователя.

+1

Хм ... Я начинаю соединять точки. Это, безусловно, самый полезный ответ. Но не могли бы вы объяснить, почему код клиента, выдающий запрос GET на gmail.com, хуже кода сервера? Я думаю, что я понимаю, почему, но для того, чтобы это было полным ответом, важно обратиться к «почему я не могу обойти все это с помощью серверного прокси». – Domenic

+2

@ Domenic - См. Мои обновления. Когда клиентский код делает запрос, куки-файлы передаются неявно. Эти файлы cookie позволяют междоменному серверу идентифицировать пользователя и, следовательно, возвращать персонализированные данные. Прокси-сервер на стороне сервера не будет иметь доступа к этим куки, поэтому он не может читать личные данные. –

+0

Отлично, спасибо! Особенно полезно, что вы явно указали файлы cookie и основные учетные данные; Я думал о куках. – Domenic

4

Рассмотрим такой сценарий ...

  1. Идешь на мой вредоносный веб-сайт.
  2. Мой сайт делает XHR на ваш банковский сайт и запрашивает форму для банковского перевода.
  3. XHR читает токен, который предотвращает CSRF и POST-форму вместе с маркером безопасности и перечисляет денежную сумму на мою учетную запись.
  4. (I) Прибыль !!!

Без той же политики происхождения, вы все равно можете POST, но вы не сможете запросить токен CSRF, который предотвращает CSRF.

Код сервера не запускается на компьютере клиента.

+2

Собственно, нет. Такая же политика происхождения предотвращает * чтение с * других веб-сайтов. Это не мешает * писать на * другие веб-сайты. В общем, ни одна из существующих политик безопасности браузера не предотвращает CSRF. –

+0

@SripathiKrishnan Я обновил сообщение, чтобы надеяться сделать его немного яснее. – alex

+0

Ой, извините. Я пропустил бит «просит токена» в вашем ответе. Я думал, вы хотели сказать, что одна и та же политика происхождения предотвращает CSRF. –

2

Основная проблема с XHR заключается в том, что они не могут просто отправить запрос, но вы также можете прочитать ответ. Отправка почти произвольных запросов уже возможна. Но читать их ответы не было. Вот почему исходный XHR не разрешал никаких запросов на перекрестный поиск вообще.

Позже, когда возникла потребность в запросах на перекрестное происшествие с XHR, CORS была создана для разрешения запросов на перекрестное происхождение при определенных условиях. Одним из условий является то, что для конкретных методов запросов, полей заголовка запроса и запросов, которые должны содержать учетные данные пользователя, требуется так называемый запрос preflight, с помощью которого клиент может проверить, разрешит ли сервер запрос. При этом сервер имеет возможность ограничивать доступ только к конкретному происхождению, так как иначе любое происхождение могло отправлять запросы.

+0

Правильно, я понимаю, как работает CORS, но почему может читать ответ опасным? – Domenic

+1

Хотя это документ, который инициирует запрос, это браузер пользователя, который фактически отправляет запрос. И браузер отправит с ним любые учетные данные, как если бы пользователь запросил его напрямую. Ответ может содержать конфиденциальную информацию, которая должна быть доступна только пользователю, но затем может инициировать инициирующий скрипт. Вот почему исходный XHR не разрешал никаких запросов на перекрестный поиск. – Gumbo

+1

Но теперь «расширенный» XHR (ранее известный как XHR level 2) разрешает запросы с кросс-началом, когда соблюдаются правила CORS. – Gumbo

Смежные вопросы