Domanda

Questo è strano, mi chiedevo se qualcuno potesse far luce sul perché è successo.

Fondamentalmente, mi sto strappando i capelli cercando di testare JSONP in modo da poter implementare un servizio web JSON che altri siti possano utilizzare.Sto sviluppando su localhost, in particolare Visual Studio 2008 e il server Web integrato di Visual Studio 2008.

Quindi, durante l'esecuzione di un test JSONP con jQuery, ho implementato quanto segue:

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

E sul server...

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

Quindi ciò che finisce è che ho impostato un punto di interruzione sul server e ottengo il punto di interruzione sia sul primo "debugger"; Stament nello script lato client e sul server.L'URL JSONP viene effettivamente richiamato dopo il caricamento della pagina.Funziona alla grande.

Il problema che stavo riscontrando era che il callback non sarebbe mai stato eseguito.L'ho provato sia in IE8 che in Firefox 3.5.Nessuno dei due invocherebbe la richiamata.Nemmeno il problema (err) è mai stato raggiunto.Non è successo proprio niente!

Sono rimasto bloccato su questo per una settimana e ho anche provato con una richiesta HTTP digitata manualmente in Telnet sulla porta specificata per essere sicuro che il server restituisca il formato...

callbackfn({abc : 'def'})

..e questo è.

Poi mi è venuto in mente, cosa succederebbe se cambiassi il nome host da localhost a localhost con un globalizzatore ('.'), cioè http://localhost.:41559/ invece di http://localhost:41559/ (sì, aggiungere un punto a qualsiasi nome host è legale, lo è per DNS cosa global:: è negli spazi dei nomi C#).E poi ha funzionato!Internet Explorer e Firefox 3.5 finalmente mi hanno mostrato un messaggio di avviso quando ho appena aggiunto un punto.

Quindi questo mi fa chiedere: cosa sta succedendo qui?Perché la generazione tardiva dei tag di script dovrebbe funzionare con un nome host Internet e non con il semplice localhost?Oppure è la domanda giusta?

Chiaramente questo è implementato per motivi di sicurezza, ma cosa stanno cercando di proteggere??E, facendolo funzionare con un punto, ho appena scoperto una falla di sicurezza in questa funzionalità di sicurezza?

A proposito, il mio file host, sebbene modificato per altri host, non ha nulla di speciale con localhost;il valore predefinito 127.0.0.1 / ::1 è ancora in vigore senza sostituzioni di seguito.

SEGUITO: Ho superato questo problema per scopi di sviluppo locale aggiungendo:

127.0.0.1   local.mysite.com

..al mio file host, quindi aggiungendo il seguente codice al mio 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);
    }
}
È stato utile?

Soluzione

Ho intenzione di dare una risposta là fuori; dopo qualche pensiero ho raggiunto le mie conclusioni.

È possibile che questa sia una funzionalità di sicurezza implementata per tentare di contrastare un sito Web Internet dall'invocazione di servizi JSONP in esecuzione sul computer client.

Un sito web potrebbe semplicemente passare attraverso un elenco di porte e continuare a invocare localhost su porte e percorsi diversi. 'Localhost' è uno dei pochi nomi host DNS che hanno un significato dinamico a seconda di quando e dove viene interrogato, rendendo vulnerabili i potenziali target. E sì, il fatto che l'aggiunta di un punto (.) A 'localhost' ('localhost.') Produca una soluzione funzionante espone una vulnerabilità di sicurezza, ma offre una soluzione [provvisoria] per gli studenti di sviluppo.

Un approccio migliore è mappare l'IP di loopback su una nuova voce del nome host nel file hosts in modo che funzioni localmente, non è incline a essere " fixed " tramite un aggiornamento del browser e non funziona in nessun altro posto se non sulla workstation di sviluppo.

Altri suggerimenti

Sto riscontrando un problema simile.La maggior parte delle soluzioni che ho provato funzionano con IE (7), ma ho difficoltà a far funzionare Firefox (3.5.2).

Ho installato HttpFox per vedere come le risposte del mio server vengono interpretate sul client e ricevo NS_ERROR_DOM_BAD_URI.La mia situazione è però leggermente diversa dalla tua, poiché sto provando a richiamare una chiamata JSONP allo stesso sito da cui proviene la pagina di hosting, e quindi questa chiamata risponde con un reindirizzamento 302 a un altro sito.(Sto utilizzando il reindirizzamento come un modo conveniente per restituire al browser i cookie di entrambi i domini.)

Sto usando jQuery e inizialmente ho provato a eseguire una chiamata AJAX standard tramite $.ajax().Ho pensato che, poiché la richiesta iniziale era rivolta allo stesso sito della pagina di hosting, Firefox avrebbe semplicemente seguito la risposta 302 a un altro dominio.Ma no, sembrava che si fosse scontrato con le difese XSS.(Nota che contrariamente a quanto Restituzione del reindirizzamento come risposta alla richiesta XHR implica, jQuery segue il reindirizzamento 302 per una chiamata dataType="json" standard:un reindirizzamento allo stesso dominio funziona correttamente;un reindirizzamento a un altro dominio genera NS_ERROR_DOM_BAD_URI nel browser.) Per inciso, non vedo perché i reindirizzamenti 302 dello stesso dominio ad altri domini non possano essere semplicemente seguiti: dopo tutto, è il dominio della pagina di hosting che sta emettendo il reindirizzamento , quindi perché non ci si può fidare?Se sei preoccupato per gli attacchi di scripting injection, il percorso JSONP è comunque aperto agli abusi...

$.getJSON() di jQuery con un ?callback=?il suffisso fallisce anche in Firefox con lo stesso errore.Così come l'utilizzo di $.getScript() per eseguire il rollio del mio tag JSONP <script>.

Ciò che sembra funzionare è avere uno <script id="jsonp" type="text/javascript"></script> preesistente nell'HTML e quindi utilizzare $("jsonp").attr("src", url + "?callback=myCallback") per richiamare la chiamata JSONP.Se lo faccio, viene seguito il reindirizzamento 302 tra domini e la mia risposta JSON viene passata a myCallback (che ho definito contemporaneamente al tag <script/>).

E sì, sto sviluppando tutto questo usando Cassini con localhost:porta URL.Cassini non risponderà a URL non localhost, quindi non posso provare facilmente local.mysite.com per vedere se ciò ha qualche effetto sulle soluzioni che ho provato sopra.Tuttavia, incollare un punto alla fine di localhost sembra aver risolto tutti i miei problemi!

Ora posso tornare a un file $.ajax({ ...tipodati:"jsonp" ...}) chiamata con localhost__.__:porta invece di localhost:porta e tutto va bene.Trovo interessante la modifica dell'attributo src di un tag script che preesiste nell'HTML della pagina fa consentire l'invocazione degli URL localhost ordinari: immagino che, seguendo il tuo processo di pensiero, questa potrebbe essere un'altra vulnerabilità della sicurezza.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top