stringtranslate.com

Fijación de sesión

En seguridad de redes informáticas, los ataques de fijación de sesión intentan explotar la vulnerabilidad de un sistema que permite a una persona fijar (encontrar o configurar) el identificador de sesión de otra persona . La mayoría de los ataques de fijación de sesión se basan en la web y dependen de que los identificadores de sesión se acepten a partir de URL ( cadenas de consulta ) o datos POST.

Escenarios de ataque

Alice tiene una cuenta en el bancohttp://unsafe.example.com/

Mallory pretende quitarle a Alice el dinero del banco.

Alice tiene un nivel razonable de confianza en Mallory y visitará los enlaces que Mallory le envíe.

Un escenario de ataque simple

Escenario sencillo:

  1. Mallory ha determinado que http://unsafe.example.com/acepta cualquier identificador de sesión, acepta identificadores de sesión de cadenas de consulta y no tiene validación de seguridad, http://unsafe.example.com/por lo que no es seguro.
  2. Mallory le envía un correo electrónico a Alice: "Oye, mira esto, hay una nueva función de resumen de cuenta genial en nuestro banco http://unsafe.example.com/?SID=I_WILL_KNOW_THE_SID". Mallory está intentando fijar el SID en I_WILL_KNOW_THE_SID.
  3. Alice está interesada y visita http://unsafe.example.com/?SID=I_WILL_KNOW_THE_SID. Aparece la pantalla de inicio de sesión habitual y Alice inicia sesión.
  4. Mallory visita http://unsafe.example.com/?SID=I_WILL_KNOW_THE_SIDy ahora tiene acceso ilimitado a la cuenta de Alice.

Ataque utilizando SID generado por servidor

Un error común es creer que si un servidor solo acepta identificadores de sesión generados por el servidor, está a salvo de la fijación. Esto es falso .

Guión:

  1. Mallory visita http://vulnerable.example.com/y verifica qué SID se devuelve. Por ejemplo, el servidor puede responder: Set-Cookie: SID=0D6441FEA4496C2.
  2. Mallory ahora puede enviarle un correo electrónico a Alice: "Mira esta nueva y genial función de nuestro banco http://vulnerable.example.com/?SID=0D6441FEA4496C2".
  3. Alice inicia sesión con el identificador de sesión fijado SID=0D6441FEA4496C2.
  4. Mallory visita http://vulnerable.example.com/?SID=0D6441FEA4496C2y ahora tiene acceso ilimitado a la cuenta de Alice.

Ataques que utilizan cookies entre subdominios

Este tipo de ataque es similar a un ataque de cookies entre sitios, excepto que no depende de la vulnerabilidad del navegador del usuario, sino del hecho de que un subdominio puede configurar cookies comodín y que esas cookies pueden afectar a otros subdominios.

Guión:

  1. Un sitio web www.example.comdistribuye subdominios a terceros que no son de confianza
  2. Una de esas partes, Mallory, que ahora controla evil.example.com, atrae a Alice a su sitio.
  3. Una visita evil.example.comestablece una cookie de sesión con el dominio .example.comen el navegador de Alice
  4. Cuando Alice visita, www.example.comesta cookie se enviará con la solicitud y Alice tendrá la sesión especificada por la cookie de Mallory.
  5. Si Alice inicia sesión ahora, Mallory podrá usar su cuenta.

Cuando se complete este ataque, Mallory podrá acceder www.example.comcomo Alice.

No es esencial que un usuario inicie sesión para explotar ataques de fijación de sesión [1] y, aunque estos ataques no autenticados no se limitan a ataques de cookies entre subdominios, las implicaciones de los ataques entre subdominios son relevantes para estos escenarios no autenticados. Por ejemplo, Mallory puede proporcionar una URL de su sitio malicioso, fijando una sesión en un escenario no autenticado y usar esas técnicas para explotar su objetivo. Esto incluye escenarios que explotan tanto los escenarios no autenticados (por ejemplo, formularios o registro) como la capacidad de proporcionar al usuario una sesión establecida para omitir el inicio de sesión por completo.

Por ejemplo, supongamos que Mallory crea un usuario llamado A1ice en www.example.com e inicia sesión con ese usuario para capturar un identificador de sesión válido y actual. Luego, Mallory engaña a Alice con una URL de evil.example.com que fija esa cookie de sesión en el navegador de Alice (como se describió anteriormente) y redirige a www.example.com para finalizar una transacción en particular (o, de hecho, un uso más amplio). De este modo, Mallory puede ocultar la sesión de su inicio de sesión original, extraer datos y ejecutar operaciones como "A1ice" en "www.example.com". Si Alice fue engañada con éxito y guardó su tarjeta de crédito en la cuenta, Mallory podría realizar compras con esa tarjeta.

Contramedidas

No acepte identificadores de sesión de variables GET/POST

No se recomiendan los identificadores de sesión en URL (cadena de consulta, variables GET) o variables POST ya que simplifican este ataque: es fácil crear enlaces o formularios que establezcan variables GET/POST.

Nota: Las cookies se comparten entre las pestañas y las ventanas emergentes del navegador. Si su sistema requiere que se lo conecte con el mismo dominio (www.example.com/?code=site1 y www.example.com/?code=site2), las cookies pueden entrar en conflicto entre sí en las distintas pestañas.

Puede ser necesario enviar el identificador de sesión en la URL para superar esta limitación. Si es posible, utilice site1.example.com o site2.example.com para que no haya conflictos de dominio en las cookies. Esto puede generar costos con certificados SSL adicionales.

Este comportamiento se puede observar en muchos sitios al abrir otra pestaña e intentar realizar búsquedas en paralelo. Una de las sesiones quedará inutilizable.

La mejor solución: confirmación de identidad

Este ataque se puede evitar en gran medida modificando el ID de sesión cuando los usuarios inician sesión. Si cada solicitud específica de un usuario requiere que el usuario se autentique ("inicie sesión") en el sitio, un atacante necesitaría saber el ID de la sesión de inicio de sesión de la víctima. Sin embargo, cuando la víctima visita el enlace con el ID de sesión fijo, necesitará iniciar sesión en su cuenta para hacer algo "importante" como ella misma. En este punto, su ID de sesión cambiará y el atacante no podrá hacer nada "importante" con el ID de sesión anónimo.

Se puede utilizar una técnica similar para solucionar el problema del phishing . Si el usuario protege su cuenta con dos contraseñas, se puede solucionar en gran medida.

Esta técnica también es útil contra ataques de falsificación de solicitudes entre sitios .

Solución: Almacenar los identificadores de sesión en cookies HTTP

El identificador de sesión en la mayoría de los sistemas modernos se almacena de forma predeterminada en una cookie HTTP , que tiene un nivel moderado de seguridad siempre que el sistema de sesión ignore los valores GET/POST. [ cita requerida ] Sin embargo, esta solución es vulnerable a la falsificación de solicitudes entre sitios y no cumple con el requisito de apátrida de REST .

Solución: Utilice el identificador de sesión SSL/TLS

Al habilitar la seguridad HTTPS , algunos sistemas permiten que las aplicaciones obtengan el identificador de sesión SSL/TLS . El uso del identificador de sesión SSL/TLS es muy seguro, pero muchos lenguajes de desarrollo web no ofrecen una funcionalidad integrada sólida para ello.

Regenerar SID en cada solicitud

Una contramedida contra la fijación de sesiones es generar un nuevo identificador de sesión (SID) en cada solicitud. Si se hace esto, aunque un atacante pueda engañar a un usuario para que acepte un SID conocido, el SID no será válido cuando el atacante intente reutilizarlo. La implementación de un sistema de este tipo es sencilla, como se demuestra a continuación:

Ejemplo:

Si Mallory engaña con éxito a Alice para que visite http://victim.example.com/?SID=I_KNOW_THE_SID, esta solicitud HTTP se envía a victim.example.com:

OBTENER  /?SID=SÉ_EL_SID  HTTP / 1.1 Host :  victima.ejemplo.com

victim.example.comacepta SID=I_KNOW_THE_SID, lo que normalmente sería malo. Sin embargo, victim.example.comes seguro porque realiza la regeneración de la sesión. victim.example.comobtiene la siguiente respuesta:

HTTP / 1.1  200  OK Establecer cookie :  SID=3134998145AB331F

Alice utilizará ahora SID=3134998145AB331Funa información que Mallory desconoce y SID=I_KNOW_THE_SIDque no es válida. Por lo tanto, Mallory no podrá fijar la sesión.

Lamentablemente, la regeneración de la sesión no siempre es posible. Se sabe que ocurren problemas cuando se utiliza software de terceros, como ActiveX o applets de Java, y cuando los complementos del navegador se comunican con el servidor. El software de terceros podría provocar cierres de sesión o que la sesión se divida en dos sesiones independientes.

Si la implementación de sesiones incluye la transmisión del SID a través de variables GET o POST, esto también podría hacer que el botón "atrás" en la mayoría de los navegadores quede inutilizable, ya que el usuario estaría usando un identificador de sesión más antiguo e inválido de una solicitud anterior.

Aceptar únicamente SID generados por el servidor

Una forma de mejorar la seguridad es no aceptar identificadores de sesión que no hayan sido generados por el servidor. Sin embargo, como se indicó anteriormente, esto no evita todos los ataques de fijación de sesión.

if  ( ! isset ( $_SESSION [ 'SERVER_GENERATED_SID' ]))  {  session_destroy ();  // Destruir todos los datos en la sesión } session_regenerate_id ();  // Generar un nuevo identificador de sesión $_SESSION [ 'SERVER_GENERATED_SID' ]  =  true ;

Función de cierre de sesión

Una función de cierre de sesión es útil ya que permite a los usuarios indicar que una sesión no debe permitir más solicitudes. Por lo tanto, los ataques solo pueden ser efectivos mientras una sesión esté activa. Tenga en cuenta que el siguiente código no realiza comprobaciones de falsificación de solicitudes entre sitios , lo que potencialmente permite que un atacante obligue a los usuarios a cerrar la sesión de la aplicación web.

if  ( cerrar sesión )  {  session_destroy ();  // Destruir todos los datos en la sesión }

Tiempo de espera de los SID antiguos

Esta defensa es fácil de implementar y tiene la ventaja de proporcionar una medida de protección contra usuarios no autorizados que acceden a la cuenta de un usuario autorizado mediante una máquina que puede haber quedado desatendida.

Almacenar una variable de sesión que contenga una marca de tiempo del último acceso realizado por ese SID. Cuando se vuelva a utilizar ese SID, comparar la marca de tiempo actual con la almacenada en la sesión. Si la diferencia es mayor que un número predefinido, por ejemplo 5 minutos, destruir la sesión. De lo contrario, actualizar la variable de sesión con la marca de tiempo actual.

Destruir sesión si el referente es sospechoso

Al visitar una página, la mayoría de los navegadores web configurarán el encabezado Referrer : la página que contiene el enlace que siguió para llegar a esta página.

Cuando el usuario ha iniciado sesión en un sitio al que no es probable que se acceda a través de enlaces externos (por ejemplo, sitios web bancarios o correo web ), y el sitio no es el tipo de sitio en el que los usuarios permanecerían conectados durante un largo período de tiempo, el referente debe ser de ese sitio. Cualquier otro referente debe considerarse sospechoso. Sin embargo, si la solicitud de origen proviene de una página HTTPS, se eliminará el referente, por lo que no puede depender de este sistema de seguridad.

Por ejemplo, http://vulnerable.example.com/se podría emplear la siguiente comprobación de seguridad:

if  ( strpos ( $_SERVER [ 'HTTP_REFERER' ],  'http://vulnerable.example.com/' )  !==  0 )  {  session_destroy ();  // Destruir todos los datos en la sesión } session_regenerate_id ();  // Generar un nuevo identificador de sesión

Verificar que la información adicional sea consistente a lo largo de la sesión

Una forma de mejorar aún más la seguridad es garantizar que el usuario parezca ser el mismo usuario final (cliente). Esto dificulta un poco la fijación de la sesión y otros ataques.

A medida que más y más redes comienzan a cumplir con RFC 3704 y otras prácticas anti- spoofing , la dirección IP se vuelve más confiable como un identificador de "misma fuente". Por lo tanto, la seguridad de un sitio web se puede mejorar verificando que la dirección IP de origen sea consistente durante toda la sesión.

Esto se podría realizar de esta manera:

if  ( $_SERVER [ 'REMOTE_ADDR' ]  !=  $_SESSION [ 'PREV_REMOTEADDR' ])  {  session_destroy ();  // Destruir todos los datos en la sesión } session_regenerate_id ();  // Generar un nuevo identificador de sesión $_SESSION [ 'PREV_REMOTEADDR' ]  =  $_SERVER [ 'REMOTE_ADDR' ];

Sin embargo, hay algunos puntos a tener en cuenta antes de emplear este enfoque.

Para algunos sitios, la seguridad adicional compensa la falta de conveniencia, y para otros no.

Agente de usuario

Los navegadores se identifican a sí mismos mediante encabezados HTTP "User-Agent". Este encabezado normalmente no cambia durante el uso; sería extremadamente sospechoso si eso sucediera. Una aplicación web podría hacer uso de la detección de User-Agent para intentar evitar que usuarios maliciosos roben sesiones. Sin embargo, esto es trivial de eludir, ya que un atacante puede capturar fácilmente el user-agent de la víctima con su propio sitio y luego falsificarlo durante el ataque. Este sistema de seguridad propuesto se basa en la seguridad por oscuridad .

if  ( $_SERVER [ 'HTTP_USER_AGENT' ]  !=  $_SESSION [ 'PREV_USERAGENT' ])  {  session_destroy ();  // Destruir todos los datos en la sesión } session_regenerate_id ();  // Generar un nuevo identificador de sesión $_SESSION [ 'PREV_USERAGENT' ]  =  $_SERVER [ 'HTTP_USER_AGENT' ];

Sin embargo, hay algunos puntos a tener en cuenta antes de emplear este enfoque.

Sin embargo, el agente de usuario puede cambiar legalmente en algunos casos. Los siguientes ejemplos son los mismos usuarios.

Defensa en profundidad

La defensa en profundidad consiste en combinar varias contramedidas. La idea es sencilla: si un obstáculo es trivial de superar, varios obstáculos pueden resultar muy difíciles de superar.

Una estrategia de defensa en profundidad podría implicar:

Los referentes HTTP no se pasan con SSL/TLS (HTTPS).

El siguiente script PHP demuestra varias de estas contramedidas combinadas de manera que se pueda defender en profundidad:

si  ( se establece ( $_GET [ 'CERRAR SESIÓN' ])  ||  $_SERVIDOR [ 'DIRECCIÓN_REMOTA' ]  !==  $_SESSION [ 'DIRECCIÓN_REMOTA_ANTERIOR' ]  ||  $_SERVIDOR [ 'AGENTE_USUARIO_HTTP' ]  !==  $_SESSION [ 'AGENTE_USUARIO_ANTERIOR' ])  {  destrucción_sesión (); }session_regenerate_id ();  // Generar un nuevo identificador de sesión$_SESSION [ 'AGENTE_USUARIO_ANTERIOR' ]  =  $_SERVER [ 'AGENTE_USUARIO_HTTP' ]; $_SESSION [ 'ADD_REMOTA_ANTERIOR' ]  =  $_SERVER [ 'ADD_REMOTA' ];

Tenga en cuenta que este código compara la REMOTE_ADDR (la dirección IP del usuario) y el User-agent actuales con la REMOTE_ADDR y el User-agent de la solicitud anterior. Esto puede resultar inconveniente para algunos sitios, como se explicó anteriormente.

Véase también

Referencias

  1. ^ Artículo sobre ataques de fijación de sesión no autenticados

Enlaces externos