¿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 un navegador pudiera estar seguro de que estaba tratando con un servidor compatible con CORS antes de enviar ciertas solicitudes. Esas solicitudes se definieron como aquellas que eran potencialmente peligrosas (cambio de estado) y nuevas (no posibles antes de CORS debido a la Política del mismo origen ). El uso de solicitudes de verificación previa significa que los servidores deben aceptar (respondiendo adecuadamente a la verificación previa) a los nuevos tipos de solicitud potencialmente peligrosos que CORS hace posible.
Ese es el significado de esta parte de la especificación : "Para proteger los recursos contra las solicitudes de origen cruzado que no pudieron originarse 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 conozca esta especificación".
¿Puedes darme un ejemplo?
Imaginemos que un usuario del navegador inicia sesión en su sitio bancario en A.com
. Cuando navegan a lo malicioso B.com
, esa página incluye algunos Javascript que intenta enviar una DELETE
solicitud A.com/account
. Dado que el usuario ha iniciado sesión A.com
, esa solicitud, si se envía, incluiría cookies que identifiquen al usuario.
Antes de CORS, la Política del mismo origen del navegador habría bloqueado el envío de esta solicitud. Pero dado que el propósito de CORS es hacer posible este tipo de comunicación de origen cruzado, ya no es apropiado.
El navegador simplemente puede enviar DELETE
y dejar que el servidor decida cómo manejarlo. Pero, ¿y si A.com
no conoce el protocolo CORS? Podría seguir adelante y ejecutar lo peligroso DELETE
. Podría haber asumido que, debido a la Política del mismo origen del navegador, nunca podría recibir una solicitud de este tipo y, por lo tanto, nunca podría haberse endurecido contra tal ataque.
Para proteger dichos 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 conscientes de CORS pueden responder correctamente, lo que permite al navegador saber si es seguro enviar el mensaje o no DELETE
.
¿Por qué todo este alboroto sobre el navegador, no puede el atacante simplemente enviar una DELETE
solicitud desde su propia computadora?
Claro, pero dicha 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 Cross-Site Request Falsificación , cuando un impreso en el sitio B.com
lata POST
que A.com
con las cookies del usuario y hacer daño.
Así es. Otra forma de decir esto es que se crearon solicitudes de verificación previa para no aumentar la superficie de ataque CSRF para servidores que no son compatibles con CORS.
Pero al observar los requisitos para solicitudes "simples" que no requieren comprobaciones previas, veo que POST
todavía está permitido. ¡Eso puede cambiar el estado y eliminar datos como un DELETE
!
¡Es verdad! CORS no protege su sitio de los ataques CSRF. Por otra parte, sin CORS tampoco estás protegido de 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 anterior a CORS.
Suspiro. OK, a regañadientes acepto 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 solicitudes para un solo dominio. Por ejemplo, puede darse el caso de que las solicitudes A.com/url1
sean manejadas por un tipo de servidor y las solicitudes A.com/url2
sean manejadas por un tipo diferente de servidor. En general, no es el caso de que el servidor que maneja un solo recurso pueda garantizar la seguridad de todos los recursos en ese dominio.
Multa. Hagamos un compromiso. Creemos un nuevo encabezado CORS que permita al servidor indicar exactamente para qué recursos puede hablar, de modo que se puedan evitar solicitudes de verificación previa adicionales a esas URL.
¡Buena idea! De hecho, el encabezado Access-Control-Policy-Path
se propuso solo para este propósito. Sin embargo, en última instancia, se dejó fuera de la especificación, aparentemente porque algunos servidores implementaron incorrectamente la especificación URI de tal manera que las solicitudes a rutas que parecían seguras para el navegador no serían seguras en los servidores dañados.
¿Fue una decisión prudente que priorizó 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 condenar Internet para desperdiciar ancho de banda y duplicar la latencia solo para acomodar errores en un servidor en particular en un momento determinado?
Las opiniones difieren.
Bueno, ¿al menos los navegadores almacenarán en caché la verificación previa para una sola URL?
Si. 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 necesitan la protección que ofrecen las solicitudes de verificación previa, ¿hay alguna forma de evitarlos?
Su única opción real es asegurarse de cumplir con los requisitos para solicitudes "simples". Eso podría significar omitir encabezados personalizados que de otro modo incluiría (como X-Requested-With
), mentir sobre el Content-Type
o más.
Hagas lo que hagas, debes asegurarte de tener las protecciones CSRF adecuadas, ya que la especificación CORS no aborda el rechazo de solicitudes "simples", incluidas las inseguras POST
. Como dice la especificación : "los recursos para los que las solicitudes simples tienen una importancia distinta de la recuperación deben protegerse de la falsificación de solicitudes entre sitios".