2009-08-02 14 views
10

Esto es extraño, me preguntaba si alguien podría arrojar algo de luz sobre por qué sucedió esto.La devolución de llamada JSONP no se ejecuta al ejecutar en localhost

Básicamente, me he estado jalando tratando de probar JSONP para poder implementar un servicio web JSON que otros sitios pueden usar. Estoy haciendo desarrollo en localhost, específicamente, Visual Studio 2008 y el servidor web integrado de Visual Studio 2008.

Así como una prueba de funcionamiento JSONP w/jQuery, que implementaron las siguientes:

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

Y en el servidor ..

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

Así que lo que termina pasando es que un punto de ruptura en el servidor y yo obtenemos el punto de interrupción tanto en el primer "depurador"; declaración en el script del lado del cliente, así como en el servidor. La URL JSONP se está invocando después de que se carga la página. Eso está funcionando bien.

El problema que estaba teniendo es que la devolución de llamada nunca se ejecutará. Probé esto tanto en IE8 como en Firefox 3.5. Ninguno de los dos invocaría la devolución de llamada. La captura (err) nunca fue alcanzada, tampoco. ¡No pasó nada!

que había quedado atrapado en esto durante una semana, e incluso probado con una petición HTTP con clave manualmente en Telnet en el puerto especificado para asegurarse de que el servidor está devolviendo el formato ...

callbackfn({abc : 'def'}) 

.. y es.

Entonces caí en la cuenta, lo que si cambio el nombre de host de localhost a localhost con un globalizador (''), es decir http://localhost.:41559/ en lugar de http://localhost:41559/ (sí, la adición de un punto a cualquier nombre de host es legal, es a DNS lo que global:: es para espacios de nombres C#). ¡Y luego funcionó! Internet Explorer y Firefox 3.5 finalmente me mostraron un mensaje de alerta cuando acabo de agregar un punto.

Así que esto me hace preguntarme, ¿qué está pasando aquí? ¿Por qué la generación de etiquetas finales de scripts funcionaría con un nombre de host de Internet y no con un localhost simple? ¿O es esa la pregunta correcta?

Claramente esto se implementa por razones de seguridad, pero ¿qué están tratando de asegurar? Y, al hacer que funcione con un punto, ¿acabo de exponer un agujero de seguridad en esta característica de seguridad?

Por cierto, el archivo de mi host, aunque está alterado para otros hosts, no tiene nada de especial con localhost; el predeterminado 127.0.0.1/:: 1 sigue en su lugar sin anulaciones a continuación.

SEGUIMIENTO: llegué más allá de esto para fines de desarrollo local mediante la adición:

127.0.0.1 local.mysite.com 

.. a mi archivo de hosts, a continuación, añadir el siguiente código a mi 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

Sugiero usar herramientas como firebug y ver si la solicitud de "script" se está haciendo para las cosas JSONP, y realmente ver qué datos están volviendo. –

+0

Los datos eran válidos. Como se describió, la solución fue alejarse de localhost (el script y los datos permanecían igual) y eso lo "solucionó", pero no explica completamente lo que está sucediendo. –

+0

sí, es por eso que sugiero registrar los acontecimientos para la versión no fijada. –

Respuesta

3

Voy a arrojar una respuesta por ahí; después de pensarlo un poco, he llegado a mis propias conclusiones.

Podría ser que esta sea una característica de seguridad que se implementa para intentar impedir que un sitio web de Internet invoque los servicios JSONP que se ejecutan en la máquina cliente.

Un sitio web podría simplemente ir a través de una lista de puertos y seguir invocando localhost en diferentes puertos y rutas. 'Localhost' es uno de los pocos nombres de host DNS que tienen un significado dinámico en función de cuándo y dónde se realiza la consulta, lo que hace que los posibles destinos sean vulnerables. Y sí, el hecho de agregar un punto (.) A 'localhost' ('localhost.') Produce una solución de trabajo que expone una vulnerabilidad de seguridad, pero ofrece una solución [tentativa] para los temas de desarrollo.

Un mejor enfoque es asignar la IP de bucle invertido a una nueva entrada de nombre de host en el archivo de hosts para que funcione localmente, no sea "reparado" por una actualización del navegador, y no funciona en ningún otro lado en la estación de trabajo de desarrollo.

1

Tengo un problema similar. La mayoría de las soluciones que he probado funcionan con IE (7), pero estoy teniendo dificultades para obtener Firefox (3.5.2) para jugar a la pelota.

He instalado HttpFox para ver cómo se interpretan las respuestas de mi servidor en el cliente y obtengo NS_ERROR_DOM_BAD_URI. Sin embargo, mi situación es un poco diferente a la tuya, ya que intento invocar una llamada JSONP al mismo sitio del que proviene la página de alojamiento, y luego esta llamada responde con un redireccionamiento 302 a otro sitio. (Estoy usando la redirección como una forma conveniente de obtener cookies de ambos dominios devueltos al navegador.)

Estoy usando jQuery, y originalmente intenté hacer una llamada AJAX estándar a través de $ .ajax(). Pensé que como la solicitud inicial era para el mismo sitio que la página de alojamiento, Firefox simplemente seguiría la respuesta 302 a otro dominio. Pero no, parecía haber fallado en las defensas de XSS. (Tenga en cuenta que, al contrario de lo que implica Returning redirect as response to XHR request, jQuery sigue la redirección 302 para una llamada estándar de dataType = "json": una redirección al mismo dominio funciona bien; una redirección a otro dominio genera NS_ERROR_DOM_BAD_URI en el navegador). No veo por qué las reasignaciones 302 del mismo dominio a otros dominios no pueden seguirse, después de todo, es el dominio de la página de alojamiento que está emitiendo el redireccionamiento, entonces ¿por qué no se puede confiar en él? Si le preocupan los ataques de inyección de scripting, entonces la ruta JSONP está abierta para el abuso de todos modos ...

jQuery $ .getJSON() con a? Callback =? sufijo también falla en Firefox con el mismo error. Al igual que con $ .getScript() para rodar mi propia etiqueta JSONP <script>.

Lo que parece funcionar, está teniendo un < guión de id = tipo preexistente "jsonp" = "text/javascript" > </script > en el HTML y luego utilizando $ ("jsonp"). Attr ("src", url + "? callback = myCallback") para invocar la llamada JSONP. Si hago eso, entonces se sigue el redireccionamiento 302 entre dominios y obtengo mi respuesta JSON pasada a myCallback (que he definido al mismo tiempo como la secuencia de comandos </>).

Y, sí, estoy desarrollando todo esto usando Cassini con localhost: URL del puerto. Cassini no responderá a las URL no locales, por lo que no puedo probar local.mysite.com fácilmente para ver si eso tiene algún efecto en las soluciones que he probado anteriormente. ¡Sin embargo, al poner un punto al final de localhost parece que solucionó todos mis problemas!

Ahora puedo volver a un $ .ajax estándar ({... Tipo de datos: "jsonp" ...}) llamar con localhost __.__: puerto en lugar de localhost: puerto y todo está bien . Me parece interesante que modificar el atributo src de una etiqueta de script que preexiste en el HTML de la página hace permitir invocar URL de localhost ordinarias - supongo que siguiendo su proceso de pensamiento, esta podría ser otra vulnerabilidad de seguridad.

Cuestiones relacionadas