origin habilitar control chrome allow ajax html5 http cors preflight

ajax - habilitar - CORS: ¿Cuál es la motivación detrás de la introducción de solicitudes de verificación previa?



cors javascript (9)

Además, para los métodos de solicitud HTTP que pueden causar efectos secundarios en los datos del usuario (en particular, para los métodos HTTP que no sean GET, o para el uso de POST con ciertos tipos MIME), la especificación obliga a los navegadores a "revisar" la solicitud

Source

El intercambio de recursos de origen cruzado es un mecanismo que permite que una página web realice Solicitudes XMLHttp a otro dominio (de wikipedia ), y es bastante importante (de mí :).

He estado jugando con CORS durante los últimos días y creo que tengo un buen entendimiento de cómo funciona todo.

Entonces, mi pregunta no es sobre cómo funcionan CORS / preflight, sino sobre la razón detrás de la creación de preflights como un nuevo tipo de solicitud . No veo ninguna razón por la que el servidor A deba enviar una verificación previa (PR) al servidor B solo para averiguar si la solicitud real (RR) será aceptada o no. Sin duda, B podría aceptar / rechazar RR sin cualquier PR anterior.

Después de buscar un poco encontré esta información en www.w3.org (7.1.5):

Para proteger los recursos contra las solicitudes de origen cruzado que no pudieron originarse en ciertos agentes de usuario antes de que existiera esta especificación, se realiza una solicitud de verificación previa para garantizar que el recurso tenga conocimiento de esta especificación.

Me parece que esta es la oración más difícil de entender. Mi interpretación (mejor debería llamarlo ''la mejor suposición'') es que se trata de proteger el servidor B contra las solicitudes del servidor C que no conoce la especificación.

¿Puede alguien explicar un escenario / mostrar un problema que PR + RR resuelve mejor que RR solo?


¿No son las solicitudes pre-iluminadas sobre el rendimiento ? Con las solicitudes pre-iluminadas, un cliente puede saber rápidamente si se permite la operación antes de enviar una gran cantidad de datos, por ejemplo, en el método JSON con PUT. O antes de viajar datos confidenciales en encabezados de autenticación a través del cable.

El hecho de PUT, DELETE y otros métodos, además de los encabezados personalizados, no están permitidos de forma predeterminada (necesitan un permiso explícito con "Access-Control-Request-Methods" y "Access-Control-Request-Headers"), eso suena al igual que una verificación doble, ya que estas operaciones podrían tener más implicaciones para los datos del usuario, en lugar de solicitudes GET. Entonces, suena como:

"Vi que permite las solicitudes de sitios cruzados de http: //foo.ejemplo , PERO, ¿ ESTÁ SEGURO de que permitirá las solicitudes de BORRAR? ¿Consideró los impactos que estas solicitudes podrían causar en los datos del usuario?"

No entendí la correlación citada entre las solicitudes de verificación previa y los beneficios de los servidores antiguos. Un servicio web que se implementó antes de CORS, o sin un conocimiento de CORS, nunca recibirá NINGUNA solicitud entre sitios, ya que primero su respuesta no tendrá el encabezado "Acceso-Control-Permitir-Origen".


Aquí hay otra forma de verlo, usando el código:

<!-- hypothetical exploit on evil.com --> <!-- Targeting banking-website.example.com, which authenticates with a cookie --> <script> jQuery.ajax({ method: "POST", url: "https://banking-website.example.com", data: JSON.stringify({ sendMoneyTo: "Dr Evil", amount: 1000000 }), contentType: "application/json", dataType: "json" }); </script>

Antes del CORS, el intento de explotación anterior fallaría porque viola la política del mismo origen. Una API diseñada de esta manera no necesitaba protección XSRF, porque estaba protegida por el modelo de seguridad nativo del navegador. Era imposible que un navegador pre-CORS generara un JSON POST de origen cruzado.

Ahora aparece CORS en escena: si no fuera necesario inscribirse en CORS antes del vuelo, de repente, este sitio tendría una gran vulnerabilidad, sin que fuera culpa suya.

Para explicar por qué algunas solicitudes pueden omitir el vuelo previo, esto se responde mediante la especificación:

Una solicitud de origen cruzado simple se ha definido como congruente con las que pueden generar los agentes de usuario implementados actualmente que no cumplen con esta especificación.

Para desentrañar eso, GET no es prefabricado porque es un "método simple" como se define en 7.1.5. (Los encabezados también deben ser "simples" para evitar el vuelo previo). La justificación para esto es que la solicitud GET de origen cruzado "simple" ya se pudo realizar, por ejemplo, <script src=""> (así es como funciona JSONP). Dado que cualquier elemento con un atributo src puede desencadenar un GET de origen cruzado, sin vuelo previo al vuelo, no sería beneficioso para la seguridad que se requiera una lucha previa en XHR "simples".


CORS le permite especificar más encabezados y tipos de métodos de lo que anteriormente era posible con <img src> o <form action> origen cruzado.

Algunos servidores podrían haber sido (pobremente) protegidos con la suposición de que un navegador no puede realizar, por ejemplo, la solicitud DELETE origen cruzado o la solicitud de origen cruzado X-Requested-With encabezado X-Requested-With , por lo que tales solicitudes son "confiables".

Para asegurarse de que el servidor realmente admita CORS y no solo responda a solicitudes aleatorias, se ejecuta la verificación previa.


Considere el mundo de las solicitudes de dominios cruzados antes de CORS. Puede hacer un formulario POST estándar, o usar un script o una etiqueta de image para emitir una solicitud GET. No podría realizar ningún otro tipo de solicitud que no sea GET / POST, y no podría emitir encabezados personalizados en estas solicitudes.

Con la llegada de CORS, los autores de las especificaciones enfrentaron el desafío de introducir un nuevo mecanismo de dominio cruzado sin romper la semántica existente de la web. Eligieron hacer esto al darles a los servidores una forma de suscribirse a cualquier nuevo tipo de solicitud. Este opt-in es la solicitud de verificación previa.

Por lo tanto, las solicitudes GET / POST sin encabezados personalizados no necesitan una verificación previa, ya que estas solicitudes ya eran posibles antes de CORS. Pero cualquier solicitud con encabezados personalizados, o solicitudes PUT / DELETE, necesita una verificación previa, ya que son nuevas para la especificación CORS. Si el servidor no sabe nada sobre CORS, responderá sin ningún encabezado específico de CORS, y la solicitud real no se realizará.

Sin la solicitud de verificación previa, los servidores podrían comenzar a ver solicitudes inesperadas de los navegadores. Esto podría llevar a un problema de seguridad si los servidores no estaban preparados para este tipo de solicitudes. La verificación previa de CORS permite que las solicitudes de dominios cruzados se introduzcan en la web de manera segura.


En un navegador que admite CORS, las solicitudes de lectura (como GET) ya están protegidas por la misma política de origen: un sitio web malintencionado que intenta realizar una solicitud de dominio cruzado autenticada (por ejemplo, el sitio web de banca en línea de la víctima o la interfaz de configuración del enrutador) no poder leer los datos devueltos porque el banco o el enrutador no configuran el encabezado Access-Control-Allow-Origin .

Sin embargo, con las solicitudes de escritura (como POST), el daño se hace cuando la solicitud llega al servidor web. * Un servidor web puede verificar el encabezado de Origin para determinar si la solicitud es legítima, pero esta verificación a menudo no se implementa porque el servidor web no tiene la necesidad de CORS o del servidor web es más antigua que CORS y, por lo tanto, se supone que las POST de dominios cruzados están totalmente prohibidas por la política del mismo origen.

Es por eso que los servidores web tienen la oportunidad de optar por recibir solicitudes de escritura entre dominios .

* Esencialmente la versión AJAX de CSRF.


Pasé un tiempo confundido en cuanto al propósito de la solicitud de verificación previa, pero creo que lo tengo ahora.

La idea clave es que las solicitudes de verificación previa no son una cosa de seguridad . Más bien, son una cosa que no cambia las reglas .

Las solicitudes de verificación previa no tienen nada que ver con la seguridad, y no tienen relación con las aplicaciones que se están desarrollando ahora, con conocimiento de CORS. Más bien, el mecanismo de verificación previa beneficia a los servidores que se desarrollaron sin tener conocimiento de CORS, y funciona como una comprobación de validez entre el cliente y el servidor, ya que ambos son conscientes de CORS. Los desarrolladores de CORS sintieron que había suficientes servidores por ahí que confiaban en la suposición de que nunca recibirían, por ejemplo, una solicitud DELETE entre dominios de que inventaron el mecanismo de verificación previa para permitir que ambas partes opten por participar. Consideraron que la alternativa, que habría sido simplemente habilitar las llamadas entre dominios, habría roto demasiadas aplicaciones existentes.

Hay tres escenarios aquí:

  1. Servidores antiguos, ya no en desarrollo, y desarrollados antes de CORS. Estos servidores pueden hacer suposiciones de que nunca recibirán, por ejemplo, una solicitud DELETE entre dominios. Este escenario es el principal beneficiario del mecanismo de verificación previa. Sí, estos servicios podrían ya ser objeto de abuso por parte de un agente de usuario malintencionado o no conforme (y CORS no hace nada para cambiar esto), pero en un mundo con CORS, el mecanismo de verificación previa proporciona una "verificación de validez" adicional para que los clientes y servidores no lo hagan. romper porque las reglas subyacentes de la web han cambiado.

  2. Servidores que aún están en desarrollo, pero que contienen una gran cantidad de código antiguo y para los cuales no es factible / deseable auditar todo el código antiguo para asegurarse de que funciona correctamente en un mundo de dominios cruzados. Este escenario permite que los servidores se inscriban progresivamente en CORS, por ejemplo, diciendo "Ahora permitiré este encabezado en particular", "Ahora permitiré este verbo HTTP en particular", "Ahora permitiré que las cookies / información de autenticación sean enviado ", etc. Este escenario se beneficia del mecanismo de verificación previa.

  3. Nuevos servidores que están escritos con conocimiento de CORS. De acuerdo con las prácticas de seguridad estándar, el servidor debe proteger sus recursos ante cualquier solicitud entrante: los servidores no pueden confiar en que los clientes no hagan cosas maliciosas. Este escenario no se beneficia del mecanismo de verificación previa : el mecanismo de verificación previa no brinda seguridad adicional a un servidor que ha protegido adecuadamente sus recursos.


Siento que las otras respuestas no se enfocan en la razón por la cual la lucha previa mejora la seguridad.

Escenarios:

1) Con pre-vuelo . Un atacante falsifica una solicitud del sitio dummy-forums.com mientras el usuario se autentica en safe-bank.com
Si el Servidor no comprueba el origen y tiene algún defecto, el navegador emitirá una solicitud previa al vuelo, método OPCIONAL. El servidor no sabe nada de ese CORS que el navegador espera como respuesta, por lo que el navegador no continuará (sin daño alguno)

2) Sin pre-vuelo . Un atacante falsifica la solicitud en el mismo escenario anterior, el navegador emitirá la solicitud POST o PUT de inmediato, el servidor la acepta y podría procesarla, esto podría causar algún daño.

Si el atacante envía una solicitud directamente, de origen cruzado, desde algún host aleatorio es muy probable que esté pensando en una solicitud sin autenticación. Esa es una solicitud falsificada, pero no una xsrf. por lo que el servidor tiene comprobará las credenciales y fallará. CORS no intenta evitar que un atacante que tiene las credenciales para emitir solicitudes, aunque una lista blanca podría ayudar a reducir este vector de ataque.

El mecanismo previo al vuelo agrega seguridad y consistencia entre clientes y servidores. No sé si vale la pena el saludo extra para cada solicitud, ya que el almacenamiento en caché es fácil de usar, pero así es como funciona.


¿Cuál fue la motivación detrás de la introducción de solicitudes de verificación previa?

Se introdujeron solicitudes de verificación previa para que los navegadores pudieran estar seguros de que estaban tratando con un servidor compatible con CORS antes de enviar ciertas solicitudes. Esas solicitudes se definieron como aquellas que eran potencialmente peligrosas (cambiantes de estado) y nuevas (no es posible antes de CORS debido a la Política del mismo origen ). El uso de solicitudes de verificación previa significa que los servidores deben participar (respondiendo correctamente a la verificación previa) a los nuevos tipos de solicitudes potencialmente peligrosas que CORS hace posibles.

Ese es el significado de esta parte de la especificación : "Para proteger los recursos contra las solicitudes de origen cruzado que no pudieron provenir de ciertos agentes de usuario antes de que existiera esta especificación, se realiza una solicitud de verificación previa para garantizar que el recurso tenga conocimiento de esta especificación".

¿Puedes darme un ejemplo?

Imaginemos que un usuario de navegador está conectado a su sitio bancario en A.com . Cuando navegan a la B.com maliciosa, esa página incluye un Javascript que intenta enviar una solicitud DELETE a A.com/account . Dado que el usuario ha iniciado sesión en A.com , esa solicitud, si se envía, incluirá cookies que identifican al usuario.

Antes de CORS, la Política del mismo origen del navegador habría bloqueado el envío de esta solicitud. Pero como el propósito de CORS es hacer posible este tipo de comunicación de origen cruzado, eso ya no es apropiado.

El navegador simplemente podría enviar el DELETE directamente y dejar todo al servidor. Pero, ¿y si A.com no tiene conocimiento del protocolo CORS? Podría seguir adelante y ejecutar el peligroso DELETE . Supuso que nunca podría recibir una solicitud de este tipo debido a la Política del mismo origen del navegador, por lo que nunca fue diseñada para frustrar un ataque de este tipo.

Para proteger tales servidores que no son compatibles con CORS, entonces, el protocolo requiere que el navegador envíe primero una solicitud de verificación previa . Este nuevo tipo de solicitud es algo a lo que solo los servidores compatibles con CORS pueden responder correctamente, lo que permite al navegador saber si es seguro enviar el DELETE real o no.

¿Por qué todo este alboroto sobre el navegador, no puede el atacante simplemente enviar una solicitud de DELETE desde su propia computadora?

Claro, pero tal solicitud no incluirá las cookies del usuario. El ataque que está diseñado para prevenir se basa en el hecho de que el navegador enviará cookies (en particular, información de autenticación para el usuario) para el otro dominio junto con la solicitud.

Eso suena como una falsificación de solicitud en sitios cruzados , donde un formulario en el sitio B.com puede A.com a A.com con las cookies del usuario y causar daños.

Está bien. Otra forma de poner esto es que las solicitudes de verificación previa se crearon para no aumentar la superficie de ataque CSRF para servidores que no son compatibles con CORS.

Pero mirando los requirements para solicitudes "simples" que no requieren preflights, veo que todavía está permitido el POST . ¡Eso puede cambiar el estado y borrar datos como un DELETE !

¡Es verdad! CORS no protege su sitio de ataques CSRF. Por otra parte, sin CORS tampoco está protegido contra los ataques CSRF. El propósito de las solicitudes de verificación previa es limitar su exposición a CSRF a lo que ya existía en el mundo pre-CORS.

Suspiro. OK, acepto a regañadientes la necesidad de solicitudes de verificación previa. Pero, ¿por qué tenemos que hacerlo para cada recurso (URL) en el servidor? El servidor maneja CORS o no lo hace.

¿Estás seguro de eso? No es raro que varios servidores manejen las solicitudes de un solo dominio. Por ejemplo, puede ocurrir que las solicitudes a A.com/url1 sean manejadas por un tipo de servidor y las solicitudes a A.com/url2 sean manejadas por un tipo diferente de servidor. No suele ser el caso que el servidor que maneja un solo recurso pueda hacer garantías de seguridad sobre todos los recursos en ese dominio.

Multa. Vamos a transigir. Vamos a crear un nuevo encabezado CORS que permita al servidor indicar exactamente a qué recursos puede dirigirse, de modo que se puedan evitar las solicitudes de verificación previa adicionales a esas URL.

¡Buena idea! De hecho, el encabezado Access-Control-Policy-Path se propuso para este propósito. Sin embargo, en última instancia, se dejó fuera de la especificación, apparently porque algunos servidores implementaron incorrectamente la especificación URI de tal manera que las solicitudes de rutas que parecían seguras para el navegador no serían de hecho seguras en los servidores rotos.

¿Fue esta una decisión prudente que dio prioridad a la seguridad sobre el rendimiento, permitiendo a los navegadores implementar inmediatamente la especificación CORS sin poner en riesgo los servidores existentes? ¿O fue miope para acabar con el ancho de banda desperdiciado y duplicar la latencia para acomodar errores en un servidor en particular en un momento determinado?

Las opiniones difieren.

Bueno, al menos los navegadores guardarán en caché la verificación previa de una única URL.

Sí. Aunque probablemente no por mucho tiempo. En los navegadores WebKit, el tiempo máximo de caché de verificación previa es actualmente de 10 minutos .

Suspiro. Bueno, si sé que mis servidores son compatibles con CORS y, por lo tanto, no necesito la protección ofrecida por las solicitudes de verificación previa, ¿hay alguna forma de evitarlos?

Su única opción real es asegurarse de cumplir con los requirements para solicitudes "simples". Eso podría significar dejar de lado los encabezados personalizados que de otro modo incluirías (como X-Requested-With ), mentir sobre el tipo de Content-Type , o más.

Independientemente de lo que haga, debe asegurarse de tener implementadas las protecciones CSRF adecuadas, ya que la especificación CORS no aborda el rechazo de solicitudes "simples", incluida la POST insegura. Como lo especifica la especificación : "los recursos para los cuales las solicitudes simples tienen un significado diferente al de la recuperación deben protegerse de la falsificación de solicitudes entre sitios".