En la seguridad de las redes informáticas, los ataques de fijación de sesiones 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 sesiones se basan en la web y la mayoría se basa en que se aceptan identificadores de sesión de URL ( cadena de consulta ) o datos POST.
Escenarios de ataque
Alice tiene una cuenta en el bancohttp://unsafe.example.com/
Mallory tiene la intención de apuntar el dinero de Alice de su banco.
Alice tiene un nivel razonable de confianza en Mallory y visitará los enlaces que Mallory le envía.
Un escenario de ataque simple
Escenario sencillo:
- 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 tanto, no es seguro. - Mallory le envía a Alice un correo electrónico: "Oye, mira esto, hay una nueva característica interesante de resumen de cuenta en nuestro banco
http://unsafe.example.com/?SID=I_WILL_KNOW_THE_SID
". Mallory está tratando de fijar el SID enI_WILL_KNOW_THE_SID
. - 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. - Mallory visita
http://unsafe.example.com/?SID=I_WILL_KNOW_THE_SID
y ahora tiene acceso ilimitado a la cuenta de Alice.
Ataque utilizando SID generado por el servidor
Una idea errónea es que si un servidor solo acepta identificadores de sesión generados por el servidor, está a salvo de la fijación. Eso es falso .
Guión:
- Mallory visita
http://vulnerable.example.com/
y verifica qué SID se devuelve. Por ejemplo, el servidor puede responder:Set-Cookie: SID=0D6441FEA4496C2
. - Mallory ahora puede enviarle un correo electrónico a Alice: "Echa un vistazo a esta nueva característica interesante de nuestro banco
http://vulnerable.example.com/?SID=0D6441FEA4496C2
". - Alice inicia sesión con un identificador de sesión fijo
SID=0D6441FEA4496C2
. - Mallory visita
http://vulnerable.example.com/?SID=0D6441FEA4496C2
y ahora tiene acceso ilimitado a la cuenta de Alice.
Ataques mediante cookies de subdominio cruzado
Esto es como una cookie entre sitios, excepto que no depende de las vulnerabilidades del navegador. Más bien, se basa en el hecho de que un subdominio puede establecer cookies comodín que afectan a otros subdominios.
Guión:
- Un sitio web
www.example.com
distribuye subdominios a terceros que no son de confianza. - Uno de esos grupos, Mallory, que ahora controla
evil.example.com
, atrae a Alice a su sitio. - Una visita para
evil.example.com
establecer una cookie de sesión con el dominio.example.com
en el navegador de Alice - Cuando Alice visite
www.example.com
, esta cookie se enviará con la solicitud, como indican las especificaciones para las cookies, y Alice tendrá la sesión especificada por la cookie de Mallory. - Si Alice ahora inicia sesión, Mallory puede usar su cuenta.
Cada uno de estos escenarios de ataque tiene un resultado en el que Mallory ha logrado acceder a las funciones y los datos normalmente reservados para Alice.
Un escenario de ataque alternativo no requiere que Alice inicie sesión en un sitio. Más bien, simplemente arreglando la sesión, Mallory puede espiar a Alice y abusar de los datos que ingresa. Por ejemplo, Mallory puede usar los ataques anteriores para darle a Alice su propia sesión autenticada, por lo que Alice comenzará a usar el sitio con toda la autenticación de Mallory. Si Alice decide comprar algo en este sitio e ingresa los detalles de su tarjeta de crédito, Mallory podría recuperar esos datos (u otros datos confidenciales) revisando los datos históricos almacenados para la cuenta. Este tipo de explotación de la fijación de sesión se diferencia de los escenarios de explotación "clásicos", ya que ocurre en la parte no autenticada de una aplicación o revierte la autenticación (el atacante inicia sesión como víctima). [1]
Contramedidas
No acepte identificadores de sesión de variables GET / POST
No se recomiendan 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.
- El SID se filtra a otras personas cuando los usuarios cortan y pegan "enlaces interesantes" de la barra de direcciones en chats, foros, comunidades, etc.
- El SID se almacena en muchos lugares (registro del historial del navegador, registro del servidor web, registros del proxy, ...)
Nota: las cookies se comparten entre pestañas y ventanas emergentes del navegador. Si su sistema requiere ser atacado con el mismo dominio (www.example.com/?code=site1 y www.example.com/?code=site2), las cookies pueden entrar en conflicto entre sí entre 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 ver en muchos sitios abriendo otra pestaña e intentando hacer resultados de búsqueda uno al lado del otro. Una de las sesiones quedará inutilizable.
Mejor solución: confirmación de identidad
Este ataque se puede evitar en gran medida cambiando 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 víctima. sesión de inicio de sesión. Sin embargo, cuando la víctima visita el enlace con la identificación de sesión fija, deberá iniciar sesión en su cuenta para hacer algo "importante" como ellos mismos. 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 resolver el problema de la suplantación de identidad . Si el usuario protege su cuenta con dos contraseñas, entonces se puede resolver en gran medida.
Esta técnica también es útil contra ataques de falsificación de solicitudes entre sitios .
Solución: almacenar 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 apatridia 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 proporcionan una funcionalidad incorporada sólida para esto.
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 reutilizar el SID. La implementación de dicho sistema es simple, como lo demuestra lo siguiente:
- Obtenga el identificador de sesión anterior
OLD_SID
de la solicitud HTTP. - Si
OLD_SID
es nulo, vacío o no existe sesión con SID =OLD_SID
, cree una nueva sesión. - Genere un nuevo identificador de sesión
NEW_SID
con un generador de números aleatorios seguro. - Deje que la sesión se identifique por SID =
NEW_SID
(y ya no por SID =OLD_SID
) - Transmita el nuevo SID al cliente.
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
:
GET /? SID = I_KNOW_THE_SID HTTP / 1.1 Host : victim.example.com
victim.example.com
acepta SID=I_KNOW_THE_SID
, lo que normalmente sería malo. Sin embargo, victim.example.com
es seguro porque realiza la regeneración de la sesión. victim.example.com
obtiene la siguiente respuesta:
HTTP / 1.1 200 OK Establecer cookie : SID = 3134998145AB331F
Alice ahora usará lo SID=3134998145AB331F
que Mallory desconoce y SID=I_KNOW_THE_SID
no es válido. Por tanto, Mallory no tiene éxito en el intento de fijación de la sesión.
Desafortunadamente, la regeneración de la sesión no siempre es posible. Se sabe que surgen problemas cuando se utilizan software de terceros, como los subprogramas ActiveX o Java, y cuando los complementos del navegador se comunican con el servidor. El software de terceros podría provocar cierres de sesión o la sesión podría dividirse en dos sesiones separadas.
Si la implementación de sesiones incluye la transmisión del SID a través de variables GET o POST, esto también puede hacer que el botón "atrás" en la mayoría de los navegadores sea inutilizable, ya que el usuario estaría usando un identificador de sesión más antiguo y no válido de una solicitud anterior.
Acepte solo SID generados por el servidor
Una forma de mejorar la seguridad es no aceptar identificadores de sesión que no fueron generados por el servidor. Sin embargo, como se señaló anteriormente, esto no evita todos los ataques de fijación de sesiones.
if ( ! isset ( $ _SESSION [ 'SERVER_GENERATED_SID' ])) { session_destroy (); // Destruye todos los datos de la sesión } session_regenerate_id (); // Genera 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 podría permitir que un atacante obligue a los usuarios a cerrar sesión en la aplicación web.
if ( cerrar sesión ) { session_destroy (); // Destruye todos los datos de la sesión }
SID antiguos de tiempo de espera
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 el uso de una máquina que puede haber quedado desatendida.
Almacene 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, compare la marca de tiempo actual con la almacenada en la sesión. Si la diferencia es mayor que un número predefinido, digamos 5 minutos, destruya la sesión. De lo contrario, actualice la variable de sesión con la marca de tiempo actual.
Destruye la sesión si el referente es sospechoso
Al visitar una página, la mayoría de los navegadores web establecerán el encabezado de referencia , la página que contenía el enlace que siguió para llegar a esta página.
Cuando el usuario inicia sesión en un sitio al que no es probable que se vincule desde fuera de ese sitio (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 una gran cantidad de tiempo. tiempo, el referente debe ser de ese sitio. Cualquier otro referente debe considerarse sospechoso. Sin embargo, si la solicitud de origen es de una página HTTPS, la referencia se eliminará, por lo que no puede depender de este sistema de seguridad.
Por ejemplo, http://vulnerable.example.com/
podría emplear el siguiente control de seguridad:
if ( strpos ( $ _SERVER [ 'HTTP_REFERER' ], 'http://vulnerable.example.com/' ) ! == 0 ) { session_destroy (); // Destruye todos los datos de la sesión } session_regenerate_id (); // Genera un nuevo identificador de sesión
Verifique que la información adicional sea consistente durante toda la sesión
Una forma de mejorar aún más la seguridad es asegurarse de que el usuario parezca ser el mismo usuario final (cliente). Esto hace que sea un poco más difícil realizar la fijación de sesiones y otros ataques.
A medida que más y más redes comienzan a ajustarse a 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 coherente durante toda la sesión.
Esto podría realizarse de esta manera:
if ( $ _SERVER [ 'REMOTE_ADDR' ] ! = $ _SESSION [ 'PREV_REMOTEADDR' ]) { session_destroy (); // Destruye todos los datos de la sesión } session_regenerate_id (); // Genera un nuevo identificador de sesión $ _SESSION [ 'PREV_REMOTEADDR' ] = $ _SERVER [ 'REMOTE_ADDR' ];
Sin embargo, hay algunos puntos a considerar antes de emplear este enfoque.
- Varios usuarios pueden compartir una dirección IP. No es raro que todo un edificio comparta una dirección IP mediante NAT .
- Un usuario puede tener una dirección IP inconsistente. Esto es cierto para los usuarios detrás de los proxies (como los clientes de AOL ). También es cierto para algunos usuarios móviles / itinerantes, así como para los usuarios que están detrás de conexiones a Internet con equilibrio de carga. Los usuarios con las extensiones de privacidad IPv6 habilitadas también pueden cambiar sus direcciones de privacidad IPv6 en cualquier momento.
- No funcionará de manera confiable con clientes de doble pila, ya que las solicitudes se moverán entre IPv4 e IPv6.
- No funcionará de manera confiable con usuarios móviles, ya que los usuarios móviles también se mueven entre direcciones.
Para algunos sitios, la seguridad adicional supera la falta de conveniencia y para otros no.
Agente de usuario
Los navegadores se identifican a sí mismos por los encabezados HTTP "User-Agent". Este encabezado normalmente no cambia durante el uso; sería extremadamente sospechoso si eso sucediera. Una aplicación web puede hacer uso de la detección de agente de usuario para intentar evitar que usuarios malintencionados roben sesiones. Sin embargo, esto es trivial de evitar, ya que un atacante puede capturar fácilmente al agente de usuario de la víctima con su propio sitio y luego falsificarlo durante el ataque. Este sistema de seguridad propuesto se basa en la seguridad a través de la oscuridad .
if ( $ _SERVER [ 'HTTP_USER_AGENT' ] ! = $ _SESSION [ 'PREV_USERAGENT' ]) { session_destroy (); // Destruye todos los datos de la sesión } session_regenerate_id (); // Genera un nuevo identificador de sesión $ _SESSION [ 'PREV_USERAGENT' ] = $ _SERVER [ 'HTTP_USER_AGENT' ];
Sin embargo, hay algunos puntos a considerar antes de emplear este enfoque.
- Varios usuarios pueden tener el mismo agente de usuario del navegador en el cibercafé .
- Varios usuarios pueden tener el mismo navegador predeterminado (por ejemplo: Internet Explorer 6 en Windows XP SP3 o mini navegador en el teléfono móvil).
Pero el agente de usuario puede cambiar legalmente en algunos casos. Los siguientes ejemplos son los mismos usuarios.
- Un teléfono inteligente cuya pantalla ha girado desde la última solicitud.
Mozilla/5.0 (Linux; U; Android 2.2; en-us; DROID2 Build/VZW) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 854X480 motorola DROID2
Mozilla/5.0 (Linux; U; Android 2.2; en-us; DROID2 Build/VZW) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 480X854 motorola DROID2
- Modo de compatibilidad de Internet Explorer:
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
- Un usuario que accede a un sitio web a través de un proxy distribuido en varios servidores, no todos los cuales están actualizados a la última versión del software de proxy.
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (FlipboardProxy/0.0.5; +http://flipboard.com/browserproxy)
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (FlipboardProxy/1.1; +http://flipboard.com/browserproxy)
Defensa en profundidad
La defensa en profundidad consiste en combinar varias contramedidas. La idea es simple: si un obstáculo es trivial de superar, varios obstáculos pueden ser muy difíciles de superar.
Una estrategia de defensa en profundidad podría involucrar:
- Habilite HTTPS (para protegerse contra otros problemas)
- Configuración correcta (no acepte SID externos, establezca tiempo de espera, etc.)
- Realice session_regeneration, soporte para cerrar sesión, etc.
Las referencias HTTP no se pasan con SSL / TLS (HTTPS).
El siguiente script PHP demuestra varias de estas contramedidas combinadas en una defensa en profundidad:
if ( isset ( $ _GET [ 'LOGOUT' ]) || $ _SERVER [ 'REMOTE_ADDR' ] ! == $ _SESSION [ 'PREV_REMOTEADDR' ] || $ _SERVER [ 'HTTP_USER_AGENT' ] ! == $ _SESSION [ 'PREV_USERAGENT' ] ) { session_destroy (); }session_regenerate_id (); // Genera un nuevo identificador de sesión$ _SESSION [ 'PREV_USERAGENT' ] = $ _SERVER [ 'HTTP_USER_AGENT' ]; $ _SESSION [ 'PREV_REMOTEADDR' ] = $ _SERVER [ 'REMOTE_ADDR' ];
Tenga en cuenta que este código verifica REMOTE_ADDR (la dirección IP del usuario) y User-agent actuales con REMOTE_ADDR y User-agent de la solicitud anterior. Esto podría ser un inconveniente para algunos sitios como se discutió anteriormente.