Обратный вызов JSONP не выполняется при работе на локальном хосте

Это странно, мне было интересно, может ли кто-нибудь пролить свет на то, почему это произошло.

По сути, я вырывался из головы, пытаясь протестировать JSONP, чтобы реализовать веб-службу JSON, которую могут использовать другие сайты. Я занимаюсь разработкой на localhost - в частности, на встроенном веб-сервере Visual Studio 2008 и Visual Studio 2008.

Итак, в качестве тестового запуска JSONP с jQuery я реализовал следующее:

$().ready(function() {
  debugger;
  try {
    $.getJSON("<%= new Uri(Request.Url, "/").ToString() %>XssTest?callback=?", function(data) {
        alert(data.abc);
    });
  } catch (err) {
    alert(err);
  }
});

И на сервере ..

<%= Request["callback"] %>({abc : 'def'})

В итоге я устанавливаю точку останова на сервере и получаю ее как на первом «отладчике»; статус в клиентском скрипте, а также на сервере. URL-адрес JSONP действительно вызывается после загрузки страницы. Отлично работает.

Проблема, с которой я столкнулся, заключалась в том, что обратный вызов никогда не выполнялся. Я тестировал это как в IE8, так и в Firefox 3.5. Ни один из них не будет вызывать обратный вызов. Уловка (ошибка) тоже так и не была достигнута. Вообще ничего не произошло!

Я застрял на этом неделю и даже протестировал HTTP-запрос с ручным вводом в Telnet на указанном порту, чтобы убедиться, что сервер возвращает формат ...

callbackfn({abc : 'def'})

.. и это.

Затем меня осенило, что, если я изменю имя хоста с localhost на localhost с помощью глобализатора ('.'), То есть http://localhost.:41559/ вместо http://localhost:41559/ (да, добавив точку для любого имени хоста допустимо, для DNS это то же самое, что global:: для пространств имен C #). И тогда это сработало! Internet Explorer и Firefox 3.5, наконец, показали мне предупреждающее сообщение, когда я просто добавил точку.

Это заставляет меня задуматься, что здесь происходит? Почему поздняя генерация тегов сценариев работает с именем хоста в Интернете, а не с обычным localhost? Или это правильный вопрос?

Очевидно, это реализовано из соображений безопасности, но что они пытаются обезопасить? И, заставив его работать с точкой, я только что обнаружил брешь в этой функции безопасности?

Между прочим, мой файл hosts, хотя и изменен для других хостов, не имеет ничего особенного с localhost; значения по умолчанию 127.0.0.1 / :: 1 все еще используются без каких-либо переопределений ниже.

ПОСЛЕДУЮЩИЕ ДЕЙСТВИЯ: я отказался от этого в целях локальной разработки, добавив:

127.0.0.1   local.mysite.com

.. в мой файл hosts, а затем добавив следующий код в мой global.asax:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    if (Request.Headers["Host"].Split(':')[0] == "localhost")
    {
        Response.Redirect(
            Request.Url.Scheme
            + "://"
            + "local.mysite.com"
            + ":" + Request.Url.Port.ToString()
            + Request.Url.PathAndQuery
            , true);
    }
}

person Jon Davis    schedule 02.08.2009    source источник
comment
Я предлагаю использовать такие инструменты, как firebug, и посмотреть, выполняется ли запрос сценария для материала JSONP, и на самом деле посмотреть, какие данные возвращаются.   -  person Luca Matteis    schedule 02.08.2009
comment
Данные действительны. Как описано, обходной путь заключался в том, чтобы уйти от localhost (скрипт и данные в остальном остались прежними), и это исправило его, но не полностью объяснило, что происходит.   -  person Jon Davis    schedule 02.08.2009
comment
да, поэтому я предлагаю регистрировать события для незафиксированной версии.   -  person Luca Matteis    schedule 02.08.2009
comment
Я сделал, Лука. Спасибо за ваше предложение.   -  person Jon Davis    schedule 02.08.2009
comment
Интересно, актуально ли это: bugzilla.mozilla.org/show_bug.cgi?id=560594   -  person Matt Gibson    schedule 24.03.2011


Ответы (2)


Я собираюсь дать ответ там; немного подумав, я пришел к своим выводам.

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

Веб-сайт может просто просмотреть список портов и продолжать вызывать localhost для разных портов и путей. «Localhost» - одно из немногих имен хостов DNS, которые имеют динамическое значение в зависимости от того, когда и где он запрашивается, что делает потенциальные цели уязвимыми. И да, тот факт, что добавление точки (.) К 'localhost' ('localhost.') Дает рабочий обходной путь, действительно обнаруживает уязвимость системы безопасности, но предлагает [предварительный] обходной путь для целей разработки.

Лучшим подходом является сопоставление IP-адреса обратной связи с новой записью имени хоста в файле hosts, чтобы он работал локально, не был подвержен «исправлению» обновлением браузера и не работал где-либо еще, кроме рабочей станции разработчика. .

person Jon Davis    schedule 02.08.2009

У меня похожая проблема. Большинство решений, которые я пробовал, работают с IE (7), но мне трудно заставить Firefox (3.5.2) играть в мяч.

Я установил HttpFox, чтобы увидеть, как ответы моего сервера интерпретируются на клиенте, и я получаю NS_ERROR_DOM_BAD_URI. Моя ситуация немного отличается от вашей, поскольку я пытаюсь вызвать JSONP-вызов на тот же сайт, с которого пришла страница хостинга, а затем этот вызов отвечает перенаправлением 302 на другой сайт. (Я использую перенаправление как удобный способ получить файлы cookie из обоих доменов, возвращенные в браузер.)

Я использую jQuery, и изначально я пытался выполнить стандартный вызов AJAX через $ .ajax (). Я полагал, что, поскольку первоначальный запрос был на тот же сайт, что и страница хостинга, Firefox просто последует ответу 302 на другой домен. Но нет, похоже, он не справился с защитой XSS. (Обратите внимание, что вопреки тому, что подразумевает возврат перенаправления в качестве ответа на запрос XHR , jQuery следует перенаправлению 302 для стандартного вызова dataType = "json": перенаправление на тот же домен работает нормально; перенаправление на другой домен генерирует NS_ERROR_DOM_BAD_URI в браузере.) Кстати, я не понимаю, почему то же самое - переадресация домена 302 на другие домены не может быть просто отслежена - в конце концов, это домен хостинговой страницы, который выдает переадресацию, так почему же ему нельзя доверять? Если вас беспокоят атаки с использованием скриптовых инъекций, то маршрут JSONP в любом случае открыт для злоупотреблений ...

$ .getJSON () из jQuery с? callback =? суффикс также не работает в Firefox с той же ошибкой. Как и использование $ .getScript () для прокрутки моего собственного тега JSONP ‹script›.

Что действительно работает, так это наличие уже существующего ‹script id =" jsonp "type =" text / javascript "› ‹/script› в HTML, а затем использование $ ("jsonp"). Attr ("src", url + "? callback = myCallback"), чтобы вызвать вызов JSONP. Если я это сделаю, то будет выполнено междоменное 302 перенаправление, и я получу свой ответ JSON, переданный в myCallback (который я определил одновременно с тегом ‹script /›).

И да, я разрабатываю все это с помощью Cassini с URL-адресами localhost: port. Cassini не будет отвечать на URL-адреса, отличные от localhost, поэтому я не могу легко попробовать local.mysite.com, чтобы узнать, влияет ли это на решения, которые я пробовал выше. Однако установка точки в конце localhost, похоже, устранила все мои проблемы!

Теперь я могу вернуться к стандартному вызову $ .ajax ({... dataType: "jsonp" ...}) с localhost __.__: port вместо localhost: port и все хорошо. Мне интересно, что изменение атрибута src тега script, который уже существует в HTML-коде страницы, действительно позволяет вызывать обычные URL-адреса localhost - я думаю, следуя вашему размышлению, это может быть еще одна уязвимость безопасности .

person Community    schedule 12.08.2009