¿Qué impide que el código malicioso falsifique el encabezado "Origen" para explotar CORS?

142

Según tengo entendido, si una secuencia de comandos del lado del cliente que se ejecuta en una página de foo.com quiere solicitar datos de bar.com, en la solicitud debe especificar el encabezado Origin: http://foo.com, y la barra debe responder Access-Control-Allow-Origin: http://foo.com.

¿Qué hay para evitar que el código malicioso del sitio roh.com simplemente falsifique el encabezado Origin: http://foo.compara solicitar páginas de la barra?

Jay Lamont
fuente
2
Creo que el punto es que el dominio original desde el que se sirve la página (aquí foo.com) tiene que proporcionar el Access-Control-Allow-Originencabezado o el navegador no permite la solicitud bar.com.
Chris Hayes
2
Leer esta publicación realmente me ayudó a comprender el proceso de cors entre el navegador, el servidor de origen y el servidor de destino. html5rocks.com/en/tutorials/cors
brendonparker
55
@ChrisHayes Así no es como funciona CORS. Puede leer un poco más sobre esto mirando la especificación o esta gran página wiki de MDN sobre el tema .
Ray Nicholus el
1
@brendonparker Sí, ese es un gran artículo. Ese autor responde muchas preguntas de CORS sobre SO y también mantiene enable-cors.org .
Ray Nicholus el
44
@RayNicholus Interesante, estaba claramente lejos. Gracias por los enlaces. A juzgar por los votos en mi comentario, no soy el único que sufre bajo este engaño. Espero que esos dos regresen y aprendan (¡y eliminen sus votos!).
Chris Hayes

Respuestas:

149

Los navegadores controlan la configuración del Originencabezado y los usuarios no pueden anular este valor. Por lo tanto, no verá el Originencabezado falsificado de un navegador. Un usuario malintencionado podría elaborar una solicitud curl que establezca manualmente el Originencabezado, pero esta solicitud vendría desde fuera de un navegador y es posible que no tenga información específica del navegador (como las cookies).

Recuerde: CORS no es seguridad. No confíe en CORS para asegurar su sitio. Si está sirviendo datos protegidos, use cookies o tokens OAuth o algo más que el Originencabezado para proteger esos datos. El Access-Control-Allow-Originencabezado en CORS solo dicta qué orígenes se deben permitir hacer solicitudes de origen cruzado. No confíes en eso para nada más.

Monsur
fuente
3
Esto tiene mucho sentido. Si el navegador no permite que JavaScript anule el encabezado Origin, entonces no hay problema. Si está ejecutando solicitudes desde fuera del navegador, no tendrá las cookies. Supongo que estaba confundido porque en todos los documentos que estaba leyendo, en ninguna parte decía explícitamente que el encabezado Origin no podía ser anulado. ¡Gracias!
Jay Lamont
41
Si alguien quiere burlarse de algo, puede hacerlo. Utilizando prácticamente cualquier lenguaje de script, pueden construir solicitudes http. Perl y Python tienen bibliotecas http que hacen que esto sea bastante fácil. Las bibliotecas almacenan y envían cookies, le permiten agregar encabezados arbitrarios y brindan mucha información de depuración. Por lo tanto, los encabezados CORS son solo para dificultar el uso de JavaScript malicioso en un foro que lees para hacer algo desagradable en tu cuenta bancaria en otro dominio cuando inicias sesión en ambos en tu navegador.
Mnebuerquo
9
Y solo para aclarar, el usuario malintencionado podría simplemente generar una instancia de navegador que fue parcheada para permitirles el control manual sobre el encabezado Origin, y luego suplantar perfectamente a un usuario normal, cookies, AJAX y todo.
Jordan Rieger
10
"Los navegadores tienen el control de configurar el encabezado Origin y el usuario no puede anular este valor". Estoy seguro de que es muy fácil usar una herramienta como Fiddler2 o Charles para modificar los encabezados una vez que la solicitud abandona el navegador.
Asa
3
el usuario malintencionado podría simplemente generar una instancia del navegador que fue parcheado para permitir que el control manual de la cabecera Origen Si usted tiene acceso a la máquina hasta el punto donde se puede 'simplemente generar una instancia del navegador parcheada' (en realidad no suene tan sencillo para mí), ¿por qué no leer directamente las cookies del disco? Se almacenan en texto sin formato, ya sabes. En la vida real, las secuencias de comandos entre sitios son una amenaza real, mientras que su escenario de ataque es artificial y poco práctico.
Stijn de Witt
35

TLDR: no hay nada que impida que el código malicioso falsifique el origen. Cuando eso suceda, su servidor nunca lo sabrá y actuará según las solicitudes. A veces esas solicitudes son caras. Por lo tanto, no use CORS en lugar de ningún tipo de seguridad.


He estado jugando con CORS recientemente, y me he hecho la misma pregunta. Lo que he encontrado es que el navegador puede ser lo suficientemente inteligente como para conocer una solicitud CORS falsa cuando la ve, pero su servidor no es tan inteligente.

Lo primero que encontré fue que el Originencabezado es un nombre de encabezado prohibido HTTP que no se puede modificar mediante programación. Lo que significa que puede modificarlo en aproximadamente 8 segundos usando Modificar encabezados para Google Chrome .

Para probar esto, configuré dos dominios de Cliente y un dominio de Servidor. Incluí una lista blanca CORS en el Servidor, que permitía las solicitudes CORS del Cliente 1 pero no del Cliente 2. Probé a ambos clientes, y de hecho las solicitudes CORS del Cliente 1 tuvieron éxito mientras que el Cliente 2 falló.

Luego falsifiqué el Originencabezado del Cliente 2 para que coincida con el del Cliente 1. El servidor recibió el Originencabezado falsificado y superó con éxito la verificación de la lista blanca (o falló si eres un tipo medio vacío). Después de eso, el Servidor se desempeñó debidamente al consumir todos los recursos para los que fue diseñado (llamadas a la base de datos, envío de correos electrónicos caros, envío de mensajes SMS aún más caros, etc.). Cuando se hizo eso, el servidor felizmente envió el Access-Control-Allow-Originencabezado falso al navegador.

La documentación que he leído indica que el Access-Control-Allow-Originvalor recibido debe coincidir Originexactamente con el valor enviado en la solicitud. Coincidieron, así que me sorprendió cuando vi el siguiente mensaje en Chrome:

XMLHttpRequest no se puede cargar http://server.dev/test. El encabezado 'Access-Control-Allow-Origin' tiene un valor http://client1.dev que no es igual al origen proporcionado. http://client2.dev Por lo tanto, el origen no tiene acceso permitido.

La documentación que leí no parece ser precisa. La pestaña de red de Chrome muestra claramente los encabezados de solicitud y respuesta http://client1.dev, pero puede ver en el error que Chrome de alguna manera sabe que el origen real era http://client2.devy rechaza correctamente la respuesta. Lo que no importa en este momento porque el servidor ya había aceptado la solicitud falsificada y había gastado mi dinero.

Nocturno
fuente
2
@Nocturno, gracias por el ejemplo. Permítanme agregar mi observación. CORS se relaciona con las características de seguridad del navegador. Si un navegador seguro se modifica desde su estado original, eso podría interpretarse como el navegador posiblemente carece de una característica de seguridad.
Luka Žitnik
10
No es brillante en absoluto. Se pierde por completo el punto de CORS. Si está en condiciones de interceptar solicitudes que se originan en la máquina del usuario, puede simplemente leer sus cookies, instalar keyloggers, virusses y todas esas otras amenazas reales. CORS está allí para proteger a los usuarios honestos que inician sesión en el sitio A de un script malicioso que de alguna manera se inyectó en el sitio B. El script en el sitio B (que podría ser un fragmento de Javascript en una publicación del foro que el sitio B no escapó correctamente) acciones en el sitio A bajo la cuenta del usuario (por ejemplo, eliminar cosas, etc.), utilizando la cookie de sesión del sitio A.
Stijn de Witt
3
Esto se llama scripting entre sitios y sin CORS podría hacerse sin necesidad de obtener el control de la máquina del usuario. Ese es todo el punto. No se necesitaba control sobre la máquina del usuario porque al realizar solicitudes al sitio A, el navegador solía agregar automáticamente la cookie de sesión a la solicitud, por lo que parecía una solicitud válida del propio usuario cuando en realidad provenía de un script en algún otro sitio. La política del mismo origen lo impide y CORS se utiliza para incluir en la lista blanca los dominios a los que se les debe otorgar acceso, aunque estén en un origen diferente.
Stijn de Witt
3
@Nocturno Sí, tal vez era un poco tosco, lo siento. Su punto original se destaca. La política del mismo origen es una característica de seguridad del navegador y CORS es un mecanismo para debilitar esa seguridad al incluir en la lista blanca algunos dominios. OP necesita comprender que falsificar el encabezado Origin no es realmente viable como un "ataque", ya que no le ofrece nada que no se pueda tener con, por ejemplo, curl.
Stijn de Witt
3
@Nocturno Creo que su declaración de apertura es un poco engañosa. There's nothing stopping malicious code from spoofing the origin-> Sí, javascript no se puede configurar Origin. Sí, un usuario puede modificar su navegador / usar el violinista para cambiar el origen, pero eso no es lo que CORS defiende; los sitios web controlados por atacantes no pueden cambiar Origin, que es lo único que importa.
RJFalconer
13

Solo una humilde conclusión:

P: ¿La misma política de origen (SOP) se aplica solo por los navegadores?
A: si. Para todas las llamadas que realice dentro de un navegador, el navegador definitivamente aplica el SOP. El servidor puede o no verificar el origen de la solicitud.

P: Si una solicitud no cumple con SOP, ¿el navegador la bloquea?
R: No, está más allá de la autoridad de los navegadores. Los navegadores solo envían solicitudes de origen cruzado y esperan la respuesta para ver si el servidor señala la llamada legítima a través de Access-Control* encabezados. Si el servidor no devuelve el Access-Control-Allow-Originencabezado, no hace eco del origen de la persona que llama o no devuelve *el encabezado, entonces todo lo que hará un navegador es abstenerse de proporcionar la respuesta a la persona que llama.

P: ¿Significa que no puedo engañar Origin?
R: En el navegador y al usar secuencias de comandos, no puede anular Originya que está bajo el control del navegador. Sin embargo, si desea piratearse, puede manipular las llamadas que salen de SU navegador utilizando extensiones de navegador u otras herramientas que instale en su máquina. También puede emitir HTTPllamadas usando curl, Python, C#, etc, y alterar la Origincabecera a los servidores de truco.

P: Entonces, si puedo engañar al servidor alterando Origin, ¿significa CORSque no es seguro?
R: CORS per se no dice nada sobre seguridad, es decir, autenticación y autorización de solicitudes. Depende de los servidores inspeccionar las solicitudes y autenticarlas / autorizarlas mediante cualquier mecanismo con el que trabajen, como cookies y encabezados. Dicho esto, puede protegernos un poco más en caso de ataques como XSS:

Ejemplo: supongamos que ha iniciado sesión en su sitio web y un script malintencionado intenta enviar una solicitud al sitio web de su banco para consultar su saldo: un ataque XSS reflejado . El sitio web de su banco confía en las credenciales que provienen (aquí en nombre de) su sitio web para que la solicitud se autentique y HTTPse emita una respuesta que apunte al código malicioso. Si el sitio web de su banco no se preocupa por compartir sus puntos finales con otros orígenes, no incluyeAccess-Control-Allow-Originencabezado en la respuesta. Ahora, al llegar la solicitud, el navegador se da cuenta de que la solicitud era una solicitud Cross Origins, pero la respuesta no muestra que el servidor estaba feliz de compartir el recurso (aquí el punto final de consulta de saldo) con su sitio web. Por lo tanto, rompe el flujo, por lo tanto, el resultado devuelto nunca alcanzará el código malicioso.

Alireza
fuente
Agradable, mejor / más claro que la respuesta aceptada OMI
3dGrabber