2009-08-02 24 views
10

To dziwne, zastanawiałem się, czy ktoś mógłby rzucić nieco światła na to, dlaczego tak się stało.Oddzwanianie JSONP nie jest wykonywane podczas pracy pod adresem localhost

W zasadzie wyciągam włosy, próbując przetestować JSONP, aby móc wdrożyć usługę WWW JSON, z której mogą korzystać inne witryny. Zajmuję się rozwojem na localhost - konkretnie, Visual Studio 2008 i Visual Studio 2008 wbudowany serwer WWW.

Tak jak próbny JSONP w/jQuery, I wdrożone następujące:

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

A na serwerze ..

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

Więc co kończy się dzieje jest ustawić punkt przerwania na serwer i otrzymuję punkt przerwania zarówno na pierwszym "debuggerze;" w skryptach po stronie klienta, a także na serwerze. Adres URL JSONP jest rzeczywiście wywoływany po załadowaniu strony. To działa świetnie.

Problem polegał na tym, że wywołanie zwrotne nie zostało wykonane. Testowałem to zarówno w IE8, jak i Firefox 3.5. Żadne nie wywołałoby wywołania zwrotnego. Nie udało się też złapać haka (err). Nic się w ogóle nie wydarzyło!

bym został zatrzymany w tej sprawie przez tydzień, a nawet przetestowany z ręcznie wpust żądanie HTTP w Telnet na określonym porcie, aby mieć pewność, że serwer jest zwrócenie format ...

callbackfn({abc : 'def'}) 

.. i to jest.

Potem przyszło mi do głowy, co jeśli zmienię nazwę hosta z localhost na localhost z globalizatorem ('.'), Tj. http://localhost.:41559/ zamiast http://localhost:41559/ (tak, dodanie kropki do dowolnej nazwy hosta jest legalne, to do DNS co global:: dotyczy przestrzeni nazw C#). A potem zadziałało! Internet Explorer i Firefox 3.5 w końcu pokazały mi komunikat ostrzegawczy, kiedy właśnie dodałem kropkę.

Więc to mnie zastanawia, co tu się dzieje? Dlaczego późniejsze generowanie tagów skryptów działa z nazwą hosta internetowego, a nie zwykłym hostem lokalnym? Czy to właściwe pytanie?

Oczywiście jest to realizowane ze względów bezpieczeństwa, ale co one próbują zabezpieczyć? A po uruchomieniu go z kropką, czy właśnie ujawniłem lukę bezpieczeństwa w tej funkcji bezpieczeństwa?

Nawiasem mówiąc, mój plik hosts, podczas gdy dla innych hostów został zmieniony, nie ma nic szczególnego z localhostem; domyślne 127.0.0.1/:: 1 są nadal na miejscu, bez poniższych przesłonięć.

KONTYNUACJA: mam przeszłość to dla celów rozwoju lokalnego dodając:

127.0.0.1 local.mysite.com 

.. złożyć moi gospodarze, a następnie dodając następujący kod do mojego 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

Proponuję użyć narzędzi takich jak firebug i sprawdzić, czy żądanie "skryptu" jest wykonywane dla rzeczy JSONP, i faktycznie zobaczyć, jakie dane wraca. –

+0

Dane były prawidłowe. Zgodnie z opisem, obejściem było odejście od localhost (skrypt i dane pozostały bez zmian) i to "naprawiono", ale nie wyjaśniono w pełni, co się dzieje. –

+0

tak, dlatego sugeruję rejestrowanie zdarzeń dla niezmodyfikowanej wersji. –

Odpowiedz

3

Mam zamiar rzucić odpowiedź tam; po jakiejś myśli doszedłem do własnych wniosków.

Możliwe, że jest to funkcja zabezpieczeń zaimplementowana, aby uniemożliwić witrynie internetowej wywoływanie usług JSONP uruchomionych na komputerze klienta.

Strona internetowa może po prostu przejrzeć listę portów i kontynuować wywoływanie hosta lokalnego na różnych portach i ścieżkach. "Localhost" jest jedną z niewielu nazw hostów DNS, które mają znaczenie dynamiczne w zależności od czasu i miejsca zapytania, co potencjalnie naraża potencjalne cele. I tak, fakt, że dołączenie kropki (.) Do "localhost" ("localhost.") Tworzy działające obejście, ujawnia lukę w zabezpieczeniach, ale oferuje [próbne] obejście dla uczniów rozwijających.

Lepszym rozwiązaniem jest odwzorowanie adresu IP pętli zwrotnej na nowy wpis nazwy hosta w pliku hosts, aby działał lokalnie, nie był "naprawiony" przez aktualizację przeglądarki i nie działał nigdzie indziej poza na stanowisku programistycznym.

1

Mam podobny problem. Większość rozwiązań, które wypróbowałem, współpracuje z IE (7), ale mam problemy z odtwarzaniem Firefoksa (3.5.2).

Zainstalowałem HttpFox, aby zobaczyć, jak odpowiedzi mojego serwera są interpretowane na kliencie, a otrzymuję NS_ERROR_DOM_BAD_URI. Moja sytuacja jest trochę inna od twojej, ponieważ próbuję wywołać wywołanie JSONP z powrotem do tej samej strony, z której pochodzi strona hostująca, a następnie to połączenie odpowiada przekierowaniem 302 do innej witryny. (Używam przekierowania jako wygodnego sposobu na pobranie plików cookie z obu domen zwróconych do przeglądarki.)

Używam jQuery, a ja początkowo próbowałem wykonywać standardowe wywołanie AJAX za pomocą $ .ajax(). Doszedłem do wniosku, że ponieważ początkowe żądanie dotyczy tej samej witryny, co strona hosta, Firefox podążyłby za 302 odpowiedzią na inną domenę. Ale nie, wydawało się, że padł ofiarą obrony XSS. (Zauważ, że w przeciwieństwie do tego, co implikuje Returning redirect as response to XHR request, jQuery wykonuje przekierowanie 302 dla standardowego połączenia dataType = "json": przekierowanie do tej samej domeny działa poprawnie, przekierowanie do innej domeny generuje NS_ERROR_DOM_BAD_URI w przeglądarce). Nie widzę powodu, dla którego przekierowania z domeny 302 do innych domen nie mogą być po prostu śledzone - w końcu to domena strony hostingowej, która wydaje przekierowanie, więc dlaczego nie można jej ufać? Jeśli obawiasz się ataków iniekcyjnych przy użyciu skryptów, to i tak trasa JSONP jest otwarta na nadużycia ...

jQuery $ .getJSON() z? Callback =? Sufiks również kończy się niepowodzeniem w Firefoksie z tym samym błędem. Podobnie jak przy użyciu skryptu $ .getScript(), aby przetasować mój własny skrypt JSONP < ze znacznikiem >.

Co wydaje się działać, jest o istniejące wcześniej < skrypt id = "jsonp" type = "text/javascript" > </script > w HTML, a następnie przy użyciu $ ("jsonp"). Attr ("src", url + "? callback = myCallback"), aby wywołać wywołanie JSONP. Jeśli to zrobię, następuje przekierowanie między domenami 302 i otrzymuję odpowiedź JSON przekazaną do funkcji myCallback (którą zdefiniowałem w tym samym czasie, co znacznik </>).

I, tak, rozwijam to wszystko za pomocą Cassini z localhost: port URL. Cassini nie zareaguje na niehosta localhost, więc nie mogę łatwo wypróbować local.mysite.com, aby sprawdzić, czy ma to jakikolwiek wpływ na rozwiązania, które wypróbowałem powyżej. Jednak przyklejenie kropki na końcu localhosta wydaje się naprawić wszystkie moje problemy!

Teraz mogę wrócić do standardowego $ .ajax ({... dataType: "jsonp" ...}) zadzwonić z localhost __.__: portu zamiast localhost: port i wszystko jest dobrze . Interesujące jest to, że modyfikowanie atrybutu src tagu skryptu, który istnieje wcześniej w kodzie HTML strony, pozwala na wywoływanie zwykłych adresów URL lokalnego hosta - myślę, że po twoim procesie myślowym może to być kolejna luka w zabezpieczeniach.

Powiązane problemy