2009-08-02 5 views
10

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

В принципе, я вытягивал свои волосы, пытаясь проверить 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'}) 

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

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

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

callbackfn({abc : 'def'}) 

.. и это.

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

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

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

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

FOLLOW-UP: Я получил это в прошлом для местных целей развития, добавив:

127.0.0.1 local.mysite.com 

.. подать мои хозяева, а затем добавить следующий код в моем 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); 
    } 
} 
+0

Я предлагаю использовать такие инструменты, как firebug, и посмотреть, выполняется ли запрос «скрипт» для материала JSONP, и фактически посмотреть, какие данные возвращаются. –

+0

Данные действительны. Как описано, обходной путь состоял в том, чтобы уйти от локального хоста (сценарий и данные в остальном остались прежними) и что «исправил» его, но не полностью объясняет, что происходит. –

+0

Да, поэтому я предлагаю регистрировать события для незафиксированной версии. –

ответ

3

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

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

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

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

1

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

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

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

jQuery's $ .getJSON() с? Callback =? суффикс также терпит неудачу в Firefox с той же ошибкой. Как и использование $ .getScript(), чтобы свернуть собственный скрипт JSONP < >.

Что появляется на работе, оказывает уже существующий < скрипт ID = тип "JSONP" = "текст/JavaScript" > </скрипт > в HTML, а затем с помощью $ ("JSONP"). Attr («src», url + «? callback = myCallback»), чтобы вызвать вызов JSONP. Если я это сделаю, будет выполняться переадресация перекрестного домена 302, и я получаю ответ JSON, переданный myCallback (который я определил одновременно с тегом </>).

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

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