security - redirección - uri de redireccionamiento autorizados
¿Por qué las API del navegador restringen las solicitudes de varios dominios? (3)
XMLHttpRequest
requieren que CORS funcione entre dominios. Del mismo modo para las fuentes web, texturas WebGL y algunas otras cosas. En general, todas las API nuevas parecen tener esta restricción.
¿Por qué?
Es tan fácil de eludir: todo lo que necesita es un simple proxy del lado del servidor. En otras palabras, el código del lado del servidor no tiene prohibido realizar solicitudes entre dominios; ¿Por qué es el código del lado del cliente? ¿Cómo da esto seguridad a alguien?
Y es tan inconsistente: no puedo XMLHttpRequest
, pero puedo <script src>
o <link rel>
o <img src>
o <iframe>
. ¿Qué significa restringir XHR, etc. incluso lograr?
Considera este escenario ...
- Vas a mi sitio malicioso.
- Mi sitio hace un XHR a su sitio web bancario y solicita el formulario para transferencia bancaria.
- El XHR lee el token que evita los formularios CSRF y POST junto con el token de seguridad y transfiere una suma de dinero a mi cuenta.
- (I) Beneficio !!!
Sin la Política del mismo origen en existencia, aún podría POST ese formulario, pero no podría solicitar el token CSRF que evita los CSRF.
El código del lado del servidor no se ejecuta en la computadora del cliente.
El problema principal con XHR es que no solo pueden enviar una solicitud, sino que también puede leer la respuesta. Ya era posible enviar solicitudes casi arbitrarias. Pero leer sus respuestas no fue. Es por eso que el XHR original no permitió ninguna solicitud de origen cruzado.
Más tarde, cuando surgió la demanda de solicitudes de origen cruzado con XHR, el CORS se estableció para permitir solicitudes de origen cruzado en condiciones específicas. Una condición es que los métodos de solicitud particulares, los campos de encabezado de solicitud y las solicitudes que contendrían credenciales de usuario requieren una llamada solicitud de verificación previa con la que el cliente puede verificar si el servidor permitiría la solicitud. Con esto, el servidor tiene la capacidad de restringir el acceso solo a orígenes específicos, de lo contrario cualquier origen podría enviar solicitudes.
Si visito un sitio web malicioso, quiero estar seguro de que:
- No puedo leer mis datos personales de otros sitios web que utilizo. Piensa en attacker.com leyendo gmail.com
- No puedo realizar acciones en mi nombre en otros sitios web que uso. Creo que attacker.com transfiere fondos de mi cuenta en bank.com
La misma política de origen resuelve el primer problema. El segundo problema se denomina falsificación de solicitud entre sitios, y no se puede resolver con las restricciones de dominio cruzadas que existen actualmente.
La misma política de origen es en general consistente con las siguientes reglas:
- Regla 1: No te permite leer nada de un dominio diferente
- Regla 2: te permite escribir lo que quieras en un dominio diferente, pero la regla # 1 no te permitirá leer la respuesta.
- Regla 3: puede realizar libremente solicitudes GET entre dominios y solicitudes POST, pero no puede controlar los encabezados HTTP
Veamos cómo las diversas cosas que has enumerado se alinean con las reglas anteriores:
<img>
etiquetas<img>
permiten hacer una solicitud HTTP, pero no hay forma de leer el contenido de la imagen más que simplemente mostrarla. Por ejemplo, si hago esto<img src="http://bank.com/get/latest/funds"/>
, la solicitud se realizará (regla 2). Pero no hay forma de que el atacante vea mi saldo (regla 1).<script>
etiquetas<script>
funcionan principalmente como<img>
. Si haces algo como<script src="http://bank.com/get/latest/funds">
, la solicitud se procesará. El navegador también intentará analizar la respuesta como JavaScript y fallará.Existe un abuso bien conocido de las etiquetas
<script>
llamado JSONP, donde se confunde con el servidor de varios dominios para que pueda "leer" varios dominios. Pero sin la participación explícita del servidor de varios dominios, no puede leer la respuesta a través de la etiqueta<script>
<link>
para las hojas de estilo funcionan principalmente como etiquetas<script>
, excepto que la respuesta se evalúa como CSS. En general, no puede leer la respuesta, a menos que de alguna manera la respuesta sea un CSS bien formado.<iframe>
es esencialmente una nueva ventana del navegador. No puede leer el HTML de un iframe de dominio cruzado. Por cierto, puede cambiar la URL de un iframe entre dominios, pero no puede leer la URL. Observe cómo sigue las dos reglas que mencioné anteriormente.XMLHttpRequest
es el método más versátil para realizar solicitudes HTTP. Esto está completamente en el control de los desarrolladores; El navegador no hace nada con la respuesta. Por ejemplo, en el caso de<img>
,<script>
o<link>
, el navegador asume un formato particular y, en general, lo validará adecuadamente. Pero en XHR, no hay un formato de respuesta prescrito. Por lo tanto, los navegadores aplican la misma política de origen y le impiden leer la respuesta a menos que el sitio web de varios dominios lo permita explícitamente.Las fuentes a través de la
font-face
son una anomalía. AFAIK, solo Firefox requiere el comportamiento opt-in; otros navegadores te permiten usar fuentes como si usaras imágenes.
En resumen, la misma política de origen es consistente. Si encuentra una forma de realizar una solicitud de dominio cruzado y leer la respuesta sin el permiso explícito del sitio web de dominio cruzado, tendrá titulares en todo el mundo.
EDITAR : ¿Por qué no puedo solucionar todo esto con un proxy del lado del servidor?
Para que gmail muestre datos personalizados, necesita cookies de su navegador. Algunos sitios usan autenticación básica HTTP, en la que las credenciales se almacenan en el navegador.
Un proxy del lado del servidor no puede tener acceso a las cookies ni a las credenciales de autenticación básicas. Y así, aunque puede hacer una solicitud, el servidor no devolverá datos específicos del usuario.