¿Cuáles son los riesgos de seguridad de configurar Access-Control-Allow-Origin?

124

Recientemente tuve que configurarlo Access-Control-Allow-Originpara *poder hacer llamadas ajax entre subdominios.
Ahora no puedo evitar sentir que estoy poniendo mi entorno en riesgos de seguridad.
Por favor, ayúdame si lo estoy haciendo mal.

Hamed Momeni
fuente

Respuestas:

69

Al responder con Access-Control-Allow-Origin: *, el recurso solicitado permite compartir con cada origen. Esto básicamente significa que cualquier sitio puede enviar una solicitud XHR a su sitio y acceder a la respuesta del servidor, lo que no sería el caso si no hubiera implementado esta respuesta CORS.

Por lo tanto, cualquier sitio puede hacer una solicitud a su sitio en nombre de sus visitantes y procesar su respuesta. Si tiene algo implementado como un esquema de autenticación o autorización que se basa en algo que el navegador proporciona automáticamente (cookies, sesiones basadas en cookies, etc.), las solicitudes activadas por los sitios de terceros también los usarán.

De hecho, esto plantea un riesgo de seguridad, especialmente si permite compartir recursos no solo para los recursos seleccionados sino para todos los recursos. En este contexto, debería echar un vistazo a ¿ Cuándo es seguro habilitar CORS? .

Gumbo
fuente
2
Si puede dar un ejemplo específico de cómo el acceso de autenticación compartido representa un riesgo de seguridad, lo votaré a favor.
Petrus Theron
1
@Gumbo ¿Qué pasa con el contenido estático? (p. ej., contenido estático de cdn, como javascripts, css, htmls estáticos, etc.) ¿Hay algún problema de seguridad al configurarlos Access-Control-Allow-Origin: *? No habrá nogin, etc., ¿son públicos para todos?
Umut Benzer
2
@UmutBenzer Eso está bien.
Gumbo
25
En realidad, esta respuesta no es del todo correcta según el estándar CORS actual : "La cadena '*' no se puede usar para un recurso que admita credenciales". Por lo tanto, no puede forzar una solicitud para usar autenticación transitoria en forma de cookies, autenticación HTTP en caché o certificados SSL de cliente. Sin embargo, si el sitio web, por ejemplo, utilizara el almacenamiento local para la autenticación, eso sería un problema.
Niklas B.
2
@NiklasB: probé este escenario y Chrome sigue el estándar CORS como has mencionado. es decir, la cadena " " no es compatible con una solicitud de credenciales. Esto es lo que informa Chrome: "XMLHttpRequest no puede cargar localhost: 12346 / hello . No se puede usar un comodín" en el encabezado 'Access-Control-Allow-Origin' cuando el indicador de credenciales es verdadero. Origin ' localhost: 12345 ' por lo tanto, no se permite el acceso. El modo de credenciales de XMLHttpRequest está controlado por el atributo withCredentials ".
factotum
37

Access-Control-Allow-Origin: *es totalmente seguro agregarlo a cualquier recurso, a menos que ese recurso contenga datos privados protegidos por algo distinto a las credenciales estándar (cookies, autenticación básica, certificados de cliente TLS).

Por ejemplo: los datos protegidos por cookies son seguros

Imagine https://example.com/users-private-data, que puede exponer datos privados según el estado de inicio de sesión del usuario. Este estado usa una cookie de sesión. Es seguro agregar Access-Control-Allow-Origin: *a este recurso, ya que este encabezado solo permite el acceso a la respuesta si la solicitud se realiza sin cookies, y se requieren cookies para obtener los datos privados. Como resultado, no se filtran datos privados.

Por ejemplo: los datos protegidos por ubicación / ip / red interna no son seguros (desafortunadamente común con intranets y electrodomésticos):

Imagine https://intranet.example.com/company-private-data, que expone los datos de la empresa privada, pero solo se puede acceder si está en la red wifi de la empresa. No es seguro agregar Access-Control-Allow-Origin: *a este recurso, ya que está protegido con algo más que las credenciales estándar. De lo contrario, un script incorrecto podría usarlo como un túnel hacia la intranet.

Regla de oro

Imagine lo que vería un usuario si accediera al recurso en una ventana de incógnito. Si está contento con que todos vean este contenido (incluido el código fuente que recibió el navegador), es seguro agregarlo Access-Control-Allow-Origin: *.

JaffaTheCake
fuente
¿debería "como solo permite solicitudes sin cookies" ser "ya que solo permite solicitudes con cookies"?
DJCordhose
3
@DJCordhose no. Access-Control-Allow-Origin: *solo permite solicitudes sin cookies. He editado la respuesta para aclarar un poco.
JaffaTheCake
¿Cuál es la diferencia entre "*" y el caso sin este encabezado? ¿Es lo mismo?
Nigrimmist
Me encantaría si "De lo contrario, un script incorrecto podría usarlo como un túnel hacia la intranet" podría explicarse más.
Sam Rueby
@Nigrimmist Entonces la solicitud de verificación previa fallará y se bloqueará el acceso a los recursos
iamareebjamal
9

AFAIK, Access-Control-Allow-Origin es solo un encabezado http enviado desde el servidor al navegador. Limitarlo a una dirección específica (o deshabilitarlo) no hace que su sitio sea más seguro, por ejemplo, para los robots. Si los robots lo desean, pueden ignorar el encabezado. Los navegadores habituales (Explorer, Chrome, etc.) cumplen el encabezado de forma predeterminada. Pero una aplicación como Postman simplemente lo ignora.

El servidor no verifica realmente cuál es el 'origen' de la solicitud cuando devuelve la respuesta. Simplemente agrega el encabezado http. Es el navegador (el cliente final) el que envió la solicitud que decide leer el encabezado de control de acceso y actuar sobre él. Tenga en cuenta que en el caso de XHR puede usar una solicitud especial de 'OPCIONES' para pedir primero los encabezados.

Por lo tanto, cualquier persona con capacidades creativas de secuencias de comandos puede ignorar fácilmente todo el encabezado, lo que esté configurado en él.

Consulte también Posibles problemas de seguridad al configurar Access-Control-Allow-Origin .


Ahora para responder realmente la pregunta

No puedo evitar sentir que estoy poniendo mi entorno en riesgos de seguridad.

Si alguien quiere atacarte, puede pasar fácilmente por Access-Control-Allow-Origin. Pero al habilitar '*', le da al atacante algunos 'vectores de ataque' más para jugar, por ejemplo, utilizando navegadores web regulares que respetan ese encabezado HTTP.

Pico común
fuente
66
Mire esto desde el punto de vista de un usuario final desprevenido. Alguien puede configurar una página web maliciosa que inyecta JavaScript para pasar datos entre el sitio real y un sitio malicioso (digamos que quieren robar su contraseña). El navegador web del usuario final normalmente bloqueará esta comunicación entre sitios, pero si se establece Access-Control-Allow-Origin, se permitirá, y el usuario final no será más sabio.
Brain2000
3
Sí, Access-Control-Allow-Origin *se desaconseja configurar un sitio web malicioso que aloje scripts para robar contraseñas :-)
commonpike
66
@commonpike Tienes razón en que alguien podría hacer un script para ignorar totalmente el encabezado. Si los datos son accesibles, es accesible con o sin encabezados CORS. Sin embargo, hay otro vector de ataque que no estás considerando. Supongamos que inicio sesión en el sitio web de mi banco. Si voy a otra página y luego vuelvo a mi banco, todavía estoy conectado debido a una cookie. Otros usuarios en Internet pueden acceder a las mismas URL en mi banco que yo, pero no podrán acceder a mi cuenta sin la cookie. Si se permiten solicitudes de origen cruzado, un sitio web malicioso puede suplantar efectivamente ...
Brad
55
@commonpike ... el usuario. Dicho de otra manera, es posible que visite mi sitio (que incluso podría ser un sitio normal, sin nada sospechoso ... ¡tal vez es un sitio legítimo que fue secuestrado!) Pero un JavaScript que hace solicitudes HTTP a su banco para transferir algunos fondos a mi cuenta. El banco no sabe la diferencia entre las solicitudes de sus páginas o las solicitudes de otras páginas. Ambos tienen esa cookie que permite que la solicitud tenga éxito.
Brad
3
@commonpike Déjame darte un ejemplo más común ... uno que sucede todo el tiempo. Suponga que tiene un enrutador doméstico común, como un Linksys WRT54g o algo así. Suponga que el enrutador permite solicitudes de origen cruzado. Un script en mi página web podría realizar solicitudes HTTP a direcciones IP comunes de enrutadores (como 192.168.1.1) y reconfigurar su enrutador para permitir ataques. Incluso puede usar su enrutador directamente como un nodo DDoS. (La mayoría de los enrutadores tienen páginas de prueba que permiten pings o verificaciones simples del servidor HTTP. Se puede abusar de ellas en masa).
Brad
7

Aquí hay 2 ejemplos publicados como comentarios, cuando un comodín es realmente problemático:

Supongamos que inicio sesión en el sitio web de mi banco. Si voy a otra página y luego vuelvo a mi banco, todavía estoy conectado debido a una cookie. Otros usuarios en Internet pueden acceder a las mismas URL en mi banco que yo, pero no podrán acceder a mi cuenta sin la cookie. Si se permiten solicitudes de origen cruzado, un sitio web malicioso puede suplantar efectivamente al usuario.

- Brad

Suponga que tiene un enrutador doméstico común, como un Linksys WRT54g o algo así. Suponga que el enrutador permite solicitudes de origen cruzado. Un script en mi página web podría realizar solicitudes HTTP a direcciones IP comunes de enrutadores (como 192.168.1.1) y reconfigurar su enrutador para permitir ataques. Incluso puede usar su enrutador directamente como un nodo DDoS. (La mayoría de los enrutadores tienen páginas de prueba que permiten pings o verificaciones simples del servidor HTTP. Se puede abusar de ellas en masa).

- Brad

Siento que estos comentarios deberían haber sido respuestas, porque explican el problema con un ejemplo de la vida real.

Christian Gollhardt
fuente
8
Excepto que esto no funcionará. "La cadena '*' no se puede usar para un recurso que admita credenciales". w3.org/TR/cors/#resource-requests
bayo
@bayotop ¿Cómo distingue el navegador entre páginas que requieren autenticación y aquellas con otros datos en los encabezados?
wedstrom
Después de leer el enlace proporcionado, hay un "indicador de credenciales de soporte" que se utiliza para este propósito. Parece que se configura manualmente, por lo que, presumiblemente, si alguien no supiera cómo configurar CORS correctamente, también podría equivocarse este indicador, por lo que creo que las vulnerabilidades anteriores son posibles.
wedstrom
2
@wedstrom El indicador lo establece quien realiza la solicitud. De todos modos, los escenarios anteriores son ejemplos de ataques CSRF. Permitir el origen '*' no lo hará más vulnerable de lo que ya lo es (tal vez un poco en casos raros). En la mayoría de los casos, puede realizar la solicitud maliciosa entre sitios utilizando formularios para que CORS no importe. En los casos en que necesite hacer una solicitud AJAX, las solicitudes previas al vuelo se interpondrán (este es el punto donde entra el navegador cuando ACAO: '*' y Access-Control-Allow-Credentials: 'verdadero').
bayo
0

En un escenario en el que el servidor intenta deshabilitar el CORS por completo, configura los siguientes encabezados.

  • Access-Control-Allow-Origin: * (le dice al navegador que el servidor acepta solicitudes de sitios cruzados de cualquier ORIGEN)

  • Access-Control-Allow-Credentials: verdadero (le dice al navegador que las solicitudes de sitios cruzados pueden enviar cookies)

Hay un sistema a prueba de fallos implementado en los navegadores que generará el siguiente error

"Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’"

Entonces, en la mayoría de los escenarios, configurar 'Access-Control-Allow-Origin' *no será un problema. Sin embargo, para protegerse contra ataques, el servidor puede mantener una lista de orígenes permitidos y cada vez que el servidor recibe una solicitud de origen cruzado, puede validar el encabezado ORIGIN contra la lista de orígenes permitidos y luego repetir el mismo en Access-Control-Allow-Origin encabezamiento.

Dado que el encabezado ORIGIN no se puede cambiar con JavaScript que se ejecuta en el navegador, el sitio malicioso no podrá falsificarlo.

shadow0359
fuente