¿Por qué el Ajax cross-domain es una preocupación de seguridad?


¿Por qué se decidió que usar XMLHttpRequest para hacer llamadas XML no debería hacer llamadas a través del límite del dominio? Puede recuperar JavaScript, imágenes, CSS, iframes y casi cualquier otro contenido que se me ocurra de otros dominios. ¿Por qué no se permite que las solicitudes HTTP Ajax crucen los límites del dominio? Parece que una limitación extraña para poner, teniendo en cuenta la única manera que podría ver que se abusa, sería si alguien fuera a inyectar Javascript en la página. Sin embargo, en en este caso, simplemente podría agregar un elemento img, script o iframe al documento para que solicite la URL de terceros y la envíe al servidor.

[Editar]

Algunas de las respuestas señalan las siguientes razones, vamos a señalar las razones por las que no crean una razón importante para no permitir esto.

XSRF (Cross Site Request Forgery, también conocido como CSRF, XSRF)

Puede hacer ataques XSRF sin usar esto en absoluto. Como regla general, XMLHttpRequest no se utiliza en absoluto, simplemente porque es tan difícil hacer una XMLHttpRequest de una manera que sea compatible con todos los navegadores principales. Es mucho más fácil simplemente agregar una etiqueta img a la URL si quieres que carguen tu URL.

Publicar en el sitio de terceros

<script type="text/javascript">
  $.post("http://some-bank.com/transfer-money.php", 
         { amount: "10000", to_account: "xxxx" })
</script>

Podría lograrse con

<body onload="document.getElementById('InvisbleForm').submit()"
    <div style="display:none">
        <form id="InvisbleForm" action="http://some-bank.com/transfer-money.php" method="POST">
            <input type="hidden" name="amount" value="10000">
            <input type="hidden" name="to_account" value="xxxxx">
        </form>
    </div>
</body>

JPunyon: ¿por qué dejar la vulnerabilidad en una nueva característica

No estás creando más inseguridades. Solo está incomodando a los desarrolladores que quieren usarlo de una manera para Bien. Cualquiera que quiera usar esta función para evil (también conocido como awesome) podría usar algún otro método para hacerlo.

Conclusión

Estoy marcando la respuesta de bobince como correcta porque señaló el problema crítico. Debido a que XMLHttpRequest le permite publicar, con credenciales (cookies) en el sitio de destino, y leer los datos enviados desde el sitio, junto con el envío de las credenciales de las personas, podría orquestar un poco de javascript que enviaría una serie de formularios, incluyendo formularios de confirmación, completos con cualquier clave aleatoria generada que se puso en su lugar para tratar de evitar un XSRF. De esta manera, usted podría navegar a través del sitio de destino, como un banco, y el servidor web del banco sería incapaz de decir que no era solo un usuario regular que envía todos estos formularios.

Author: Kirill Kobelev, 2009-01-21

9 answers

¿Por qué no se permite que las solicitudes HTTP Ajax crucen los límites de dominio?

Porque las solicitudes AJAX (a) se envían con credenciales de usuario, y (b) permiten al llamante leer los datos devueltos.

Es una combinación de estos factores que puede resultar en una vulnerabilidad. Hay propuestas para agregar una forma de AJAX entre dominios que omita las credenciales de usuario.

Simplemente puede agregar un elemento img, script o iframe al documento

Ninguno de estos métodos permiten al llamante leer los datos devueltos.

(Excepto los scripts donde está deliberadamente configurado para permitir eso, para permitir el scripting entre dominios-o donde alguien ha cometido un terrible error.)

Puede hacer ataques XSS sin usar esto en absoluto. Publicar en el sitio de terceros

Eso no es un ataque XSS. Eso es un ataque de falsificación de solicitud entre sitios (XSRF). Existen formas conocidas de resolver ataques XSRF, como incluir ataques únicos o tokens criptográficos para verificar que el envío provino deliberadamente del usuario y no se lanzó desde el código del atacante.

Si permitieras el AJAX entre dominios perderías esta protección. El código atacante podría solicitar una página del sitio bancario, leer cualquier token de autorización en él y enviarlos en una segunda solicitud AJAX para realizar la transferencia. Y eso sería un ataque de scripting entre sitios.

 36
Author: bobince,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-21 20:53:22

Una diferencia importante entre el POST:

<body onload="document.getElementById('InvisbleForm').submit()" ...

Y Ajax es que después de hacer cualquier POST el navegador reemplazará la página y después de hacer la llamada Ajax-not. El resultado del POST será:

  1. Claramente visible para el usuario.
  2. El ataque se atascará en este punto porque la página de respuesta de my-bank.com tomará el control. Ningún banco implementará una transferencia de un solo clic.

El escenario de XSRF, si el dominio cruzado Ajax se permitirá, se verá como el siguiente:

  1. El usuario de alguna manera visita www.bad-guy.com.
  2. Si no hay una página abierta a my-bank.com en otra instancia del navegador, el ataque no tiene éxito.
  3. Pero si se abre dicha página y el usuario ya ha introducido su nombre de usuario/contraseña, esto significa que hay una cookie para esta sesión en la caché del navegador.
  4. El código JavaScript en la página de www.bad-guy.com hace una llamada Ajax a my-bank.com.
  5. Para el navegador esto es un Llamada HTTP, tiene que enviar las cookies de my-bank a my-bank.com y las envía.
  6. Bank procesa esta solicitud porque no puede distinguir esta llamada de la actividad regular del usuario.
  7. El hecho de que el código JavaScript pueda leer la respuesta no es importante. En el caso del ataque, esto podría no ser necesario. Lo que es realmente importante es que el usuario frente a la computadora no tendrá idea de que esta interacción tiene lugar. Él mirará las imágenes agradables en el www.bad-guy.com pagina.
  8. El código JavaScript hace varias otras llamadas a my-bank.com si es necesario.

Lo esencial es que no se necesita ninguna inyección o manipulación de la página.

Una mejor solución podría ser permitir la llamada en sí, pero no enviar ninguna cookie. Esta es una solución muy simple que no requiere ningún desarrollo extenso. En muchos casos la llamada Ajax va a una ubicación desprotegida y no enviar cookies no será una limitación.

Los CORS (Intercambio de Recursos de Origen Cruzado) que se está discutiendo ahora, entre otras cosas, habla de enviar / no enviar cookies.

 7
Author: Kirill Kobelev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-24 08:43:59

Bueno, aparentemente no eres la única persona que se siente así...

Http://www.google.com/search?q=xmlhttp + cross + site

EDITAR: Hay una discusión interesante vinculada a la búsqueda anterior:

Http://blogs.msdn.com/ie/archive/2008/06/23/securing-cross-site-xmlhttprequest.aspx

Parece que las propuestas están en curso para permitir solicitudes xmlhttp de sitios cruzados (ES decir, 8, FF3, etc.), aunque desearía que hubieran estado allí cuando estaba escribiendo el código para mis sitios :) Y luego está el problema de la compatibilidad... Pasará un tiempo antes de que sea omnipresente.

 2
Author: Andrew Rollings,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-21 20:11:41

Cuando envía una solicitud HTTP al servidor, las cookies establecidas por el servidor también se envían de vuelta por el navegador al servidor. El servidor utiliza estas cookies para establecer que el usuario ha iniciado sesión, etc.

Esto puede ser explotado por un atacante malicioso que, con la ayuda de algún JavaScript, puede robar información o realizar comandos no autorizados en otros sitios web sin que el usuario sepa nada al respecto.

Por ejemplo, se podría pedir a un usuario que visite un sitio que tiene el siguiente código JavaScript (asumiendo jQuery):

<script type="text/javascript">
  $.post("http://some-bank.com/transfer-money.php", 
         { amount: "10000", to_account: "xxxx" })
</script>

Ahora, si el usuario realmente hubiera iniciado sesión en el banco mientras se ejecutaba el código anterior, el atacante podría haber transferido USD 10K a la cuenta XXX.

Este tipo de ataques se llaman Cross Site Request Forgery (XSRF). Hay más información sobre esto en Wikipedia.

Se debe principalmente a esta razón por la que existe la política del mismo origen y los navegadores no le permitirán realizar XMLHttpRequests en dominios diferente del origen.

Hay cierta discusión sobre permitir XHR entre dominios, pero tenemos que ver si esto realmente se acepta.

 2
Author: Baishampayan Ghose,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-21 20:18:28

Es una preocupación porque puede ser utilizado para malos propósitos, como usted mencionó. También se puede utilizar con buena intención, y por esa razón, se están desarrollando protocolos de dominio cruzado.

Las dos mayores preocupaciones son cuando se usa junto con cross-site scripting (XSS) y cross-site request forgery (CSRF). Ambos son amenazas serias (por lo que llegaron al top 10 de OWASP y al SANS 25).

La única manera en que podría ver que se abusa, sería si alguien iba a inyectar Javascript

Esto es XSS Demasiadas aplicaciones siguen siendo vulnerables, y si los modelos de seguridad del navegador no impiden X-domain AJAX, están abriendo a sus usuarios a un vector de ataque considerable.

Simplemente puede agregar un elemento img, script o iframe al documento para que solicite la URL de terceros

Sí, pero esos enviarán un HTTP_REFERRER y (a través de otros medios) se pueden bloquear para evitar CSRF. Llamadas AJAX pueden suplantar los encabezados más fácilmente y permitirían otros medios de eludir las protecciones CSRF tradicionales.

 1
Author: Mike Griffith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-21 20:28:17

Creo que otra cosa que separa esto de un ataque XSRF normal es que puedes hacer cosas con los datos que recuperas también a través de javascript.

 1
Author: Shawn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-21 20:34:53

No se cual es el gran problema? Haga que las llamadas AJAX se envíen a otros dominios primero a su aplicación y luego se reenvíen a otro lugar con datos filtrados, analice los datos devueltos si realmente lo necesita y aliméntelos al usuario.

¿Manejando solicitudes AJAX sensibles? Clavar hacia abajo las ventosas entrantes mediante la comprobación de encabezados, el almacenamiento de datos de tiempo de sesión o filtrando las direcciones IP entrantes a las fuentes de su confianza o sus aplicaciones.

Lo que personalmente me gustaría ver en el futuro es una seguridad sólida como una roca en todas las solicitudes entrantes de forma predeterminada en servidores web, marcos y CMSs, y luego definir explícitamente los recursos que analizarán las solicitudes de fuentes externas.

 1
Author: Filip Dupanović,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-21 20:48:59

Con <form> puede publicar datos, pero no puede leerlos. Con XHR puedes hacer ambas cosas.

Página como http://bank.example.com/display_my_password es segura contra XSRF (suponiendo que solo muestra y no establece la contraseña) y marcos (tienen política del mismo origen). Sin embargo, cross-domain XHR sería una vulnerabilidad.

 1
Author: Kornel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-21 21:32:39

Conviertes a visitantes desprevenidos en atacantes de denegación de servicio.

También, imagina un script de sitios cruzados que roba todas tus cosas de Facebook. Abre un IFrame y navega a Facebook.com

Ya has iniciado sesión en Facebook (cookie) y va a leer tus datos/amigos. Y hace más desagradables.

 0
Author: user57660,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-21 20:09:31