Guía de gestión de sesiones web
FuncionalidadEsta guía explica detalladamente las particularidades de las sesiones en el lado servidor, una correcta gestión de las mismas y su seguridad, así como de las cookies del lado cliente. | RequisitosComunicaciones entre cliente-servidor (básico) Utilización de servidores web para aplicaciones backend Desarrollos frontend con mantenimiento de las sesiones mediante cookies. |
Introducción
Breve descripción
Una sesión web es una secuencia de transacciones, solicitudes y respuestas, HTTP asociadas a un mismo usuario. Las aplicaciones web, más modernas y complejas, requieren la retención de información o estado sobre cada usuario durante la duración de las múltiples solicitudes. Por lo tanto, las sesiones otorgan la capacidad de establecer variables que se aplicarán a todas y cada una de las interacciones que un usuario tenga con la aplicación web durante la sesión.
Las aplicaciones web pueden crear sesiones para realizar un seguimiento de los usuarios anónimos tras la primera solicitud que realice (por ejemplo, para mantener la preferencia de idioma del usuario). Además, las aplicaciones web utilizan sesiones una vez que el usuario se ha autenticado para garantizar la capacidad de identificación del usuario en cualquier solicitud posterior, así como poder aplicar controles de acceso de seguridad, acceso autorizado a los datos privados del usuario y aumentar la usabilidad de la aplicación. Las aplicaciones web actuales pueden proporcionar capacidades de sesión tanto de autenticación previa como posterior. Una vez que se ha establecido una sesión autenticada, el ID de sesión (o token) es temporalmente equivalente al método de autenticación más fuerte utilizado por la aplicación.
HTTP es un protocolo sin estado (RFC2616, sección 5), donde cada par solicitud-respuesta es independiente de los demás. Por lo tanto, para introducir el concepto de sesión es necesario implementar capacidades de administración de sesión que vinculen tanto los módulos de autenticación como de control de acceso (o autorización) tan comunes en aplicaciones web:
El identificador de sesión (o token) enlaza las credenciales de autenticación del usuario (en forma de sesión de usuario) al tráfico HTTP del usuario y los controles de acceso apropiados impuestos por la aplicación web. La complejidad de estos tres componentes (autenticación, gestión de sesión y control de acceso) en aplicaciones web modernas junto con el hecho de que su implementación y enlace reside en las manos del desarrollador web (ya que el marco de desarrollo web no proporciona relaciones estrictas entre estos módulos) hace que la implementación de un módulo de administración de sesión segura sea complejo.
La divulgación, captura, predicción o fijación del ID de la sesión facilitará los ataques de secuestro de sesión, donde un atacante puede suplantar por completo a un usuario víctima en la aplicación web. Los atacantes pueden realizar dos tipos de ataques de secuestro de sesión, dirigidos o genéricos. En un ataque dirigido el objetivo del atacante es hacerse pasar por un usuario específico (o con privilegios) de la aplicación web víctima. Para los ataques genéricos el objetivo del atacante es suplantar (u obtener acceso como) a cualquier usuario válido o legítimo en la aplicación web.
Propiedades del ID de sesión
Para mantener el estado autenticado y rastrear el progreso de los usuarios dentro de la aplicación web, las aplicaciones proporcionan a los usuarios un identificador de sesión (ID de sesión o token) que se asigna en el momento de creación de la sesión, que será compartido e intercambiado entre el usuario y la aplicación web durante la sesión (se envía en cada solicitud HTTP). El ID de sesión es un par nombre=valor. Con el objetivo de implementar un ID de sesión seguro, la generación de identificadores (ID o tokens) debe cumplir con las siguientes propiedades.
Nombres de IDs de sesión poco descriptivos
El nombre utilizado por el ID de la sesión no debe ser extremadamente descriptivo ni ofrecer detalles innecesarios sobre el propósito y el significado del identificador.
Los nombres de ID de sesión utilizados por los frameworks de aplicaciones web más comunes pueden ser identificados muy fácilmente, como PHPSESSID (PHP), JSESSIONID (J2EE), CFID y CFTOKEN (ColdFusion), ASP.NET_SessionId (ASP .NET), etc. Por lo tanto, el nombre del ID de sesión puede revelar las tecnologías y los lenguajes de programación utilizados por la aplicación web.
Se recomienda cambiar el nombre del ID de sesión predeterminado a un nombre genérico, como por ejemplo simplemente ID.
Longitud del ID de sesión
El ID de la sesión debe ser lo suficientemente largo como para evitar ataques de fuerza bruta, donde un atacante puede recorrer todo el rango de posibles valores del ID y verificar la existencia de sesiones válidas.
La longitud del ID de sesión debe ser de al menos 128 bits (16 bytes).
La longitud del ID de sesión de 128 bits se proporciona como una referencia basada en los supuestos hechos que se comentan en la siguiente sección, Entropía del ID de sesión. Sin embargo, este número no debe considerarse como un valor mínimo absoluto, ya que otros factores de implementación pueden influir en su fortaleza.
Puede proporcionar una entropía efectiva buena por lo que puede considerarse lo suficientemente largo como para evitar ser adivinado o ataques de fuerza bruta.
Entropía del ID de sesión
El ID de sesión debe ser impredecible (lo suficientemente aleatorio) para evitar ataques de fuerza bruta, donde un atacante puede adivinar o predecir el ID de una sesión válida a través de técnicas de análisis estadístico. Para este propósito, se debe utilizar un buen PRNG (generador de números pseudoaleatorios).
El valor de ID de sesión debe proporcionar al menos 64 bits de entropía (si se utiliza un buen PRNG, se estima que este valor es la mitad de la longitud del ID de sesión).
La entropía del ID de sesión se ve afectada por otros factores externos y difíciles de medir, como el número de sesiones activas simultáneas de la aplicación web, el tiempo de espera absoluto de caducidad de sesión, la cantidad de intento de IDs de sesión por segundo que puede hacer el atacante y que la aplicación web de destino puede soportar, etc.
Si se utiliza un ID de sesión con una entropía de 64 bits, un atacante tardará al menos 292 años en adivinar con éxito un ID de sesión válido, suponiendo que el atacante pueda probar 10,000 intentos por segundo con 100,000 sesiones simultáneas válidas en la aplicación web.
Si se quiere obtener más detalles consulte el siguiente enlace.
Contenido del ID de sesión
El contenido (o valor) del ID de sesión no debe de ser lo más neutro y escueto posible para evitar ataques de divulgación de información, donde un atacante puede decodificar el contenido del ID y extraer detalles del usuario, la sesión o el funcionamiento interno de la aplicación web.
El ID de sesión debe ser simplemente un identificador en el lado del cliente, y su valor nunca debe incluir información confidencial o información personal privada. El significado y la lógica comercial o de aplicación asociada al ID de sesión se deben almacenar en el lado del servidor, ya sea en objetos de sesión, en una base de datos o en un repositorio de administración de sesiones.
La información almacenada puede incluir la dirección IP del cliente, User-Agent, correo electrónico, nombre de usuario, ID de usuario, rol, nivel de privilegio, derechos de acceso, preferencias de idioma, ID de cuenta, estado actual, último inicio de sesión, tiempos de espera de sesión entre otros detalles. Si los objetos y propiedades de la sesión contienen información confidencial, como números de tarjetas de crédito, es necesario encriptar y proteger debidamente el repositorio de administración de la sesión.
Se recomienda crear IDs de sesión criptográficamente fuertes mediante el uso de funciones hash criptográficas como SHA256.
Implementación de la gestión de sesiones
La implementación de la gestión de la sesión define el mecanismo de intercambio que se utilizará entre el usuario y la aplicación web para compartir e intercambiar continuamente el ID de la sesión. Existen múltiples mecanismos disponibles en HTTP para mantener el estado de la sesión dentro de las aplicaciones web, como cookies (encabezado HTTP estándar), parámetros de URL (reescritura de URL - RFC2396), argumentos de URL en solicitudes GET, argumentos en el cuerpo de la solicitud POST como campos de formulario ocultos o encabezados HTTP propietarios.
El mecanismo elegido de intercambio de IDs de sesión debe permitir definir propiedades avanzadas en el token, como la fecha y hora de caducidad del token o restricciones de uso granulares. Esta es una de las razones por las cuales las cookies (RFC 2109, 2965 y 6265) son uno de los mecanismos de intercambio de IDs de sesión más utilizados, ya que ofrecen capacidades avanzadas que no están disponibles en otros métodos.
El uso de mecanismos específicos de intercambio de IDs de sesión, como aquellos en los que el ID está incluido en la URL, pueden revelar el ID de sesión (en enlaces y registros web, historial y marcadores del navegador web, el encabezado Referer o los motores de búsqueda) así como facilitar otros ataques, como la manipulación del ID o los ataques de fijación de sesión.
Implementaciones integradas de gestores de sesión
Los frameworks web, como J2EE, ASP .NET, PHP entre otros, proporcionan sus propias funciones de administración de sesión junto con su implementación. Se recomienda usar estas funciones ya hechas en lugar de construirlas desde cero por uno mismo, ya que se usan en todo el mundo en múltiples entornos web y han sido probadas por las comunidades de seguridad y desarrollo de aplicaciones web a lo largo del tiempo.
Sin embargo, se debe de tener en cuenta que estos frameworks también han presentado vulnerabilidades y debilidades en el pasado, por lo que siempre es recomendable utilizar la última versión disponible que potencialmente corrige todas las vulnerabilidades conocidas, así como revisar y cambiar la configuración predeterminada para mejorar su seguridad.
En cuanto al almacenamiento o el repositorio utilizado por el mecanismo de administración de sesiones para guardar temporalmente los IDs de sesión deben de ser seguros, protegiendo los IDs de la sesión contra la divulgación accidental local/remota o el acceso no autorizado.
Mecanismos de intercambio de IDs de sesión: Usados versus Aceptados
Una aplicación web debe utilizar cookies para la gestión del intercambio de IDs de sesión. Si un usuario envía un ID de sesión a través de un mecanismo diferente, como un parámetro en la URL, la aplicación web debe evitar aceptarlo como parte de una estrategia defensiva con el fin de protegerse frente a los ataques de fijación de sesión.
Aunque una aplicación web utilice las cookies como mecanismo predeterminado de intercambio de IDs de sesión, también puede aceptar otros mecanismos de intercambio.
Es necesario confirmar mediante pruebas exhaustivas todos los diferentes mecanismos aceptados por la aplicación web al procesar y administrar los IDs de sesión, limitando los mecanismos de seguimiento de IDs de sesión aceptados a solo mediante cookies.
Anteriormente, algunas aplicaciones web usaban parámetros en la URL o incluso cambiaban de cookies a parámetros en la URL (mediante reescritura automática de URL) si se cumplían ciertas condiciones, como el uso de clientes web sin soporte para cookies o porque el usuario no acepta el uso de cookies por temas de privacidad.
Seguridad de la capa de transporte
A la hora de proteger el intercambio de IDs de sesión en el tráfico de red es esencial utilizar una conexión HTTPS (TLS) encriptada para toda la sesión web, no solo para el proceso de autenticación donde se intercambian las credenciales del usuario.
Además, se debe establecer el atributo Secure en la cookie para garantizar que el ID de la sesión solo se intercambie a través de un canal cifrado. El uso de un canal de comunicación cifrado también protege la sesión contra algunos ataques de fijación de sesión en los que el atacante puede interceptar y manipular el tráfico web para inyectar (o fijas) el ID de sesión en el navegador web de la víctima.
A continuación se listan una serie de buenas prácticas enfocadas en la protección de los IDs de sesión (específicamente cuando se usan cookies) y en ayudar con la integración de HTTPS dentro de una aplicación web:
No cambiar durante una sesión de HTTP a HTTPS o viceversa, ya que esto revelará el ID de la sesión a través de la red.
Al redirigir a HTTPS, se debe de asegurar de que la cookie esté configurada correctamente o regenerada después de que se haya producido la redirección.
No mezclar contenidos cifrados y no cifrados (páginas HTML, imágenes, CSS, archivos JavaScript, etc.) en la misma página o desde el mismo dominio.
Siempre que sea posible, evitar ofrecer contenidos públicos no encriptados y contenidos privados encriptados desde el mismo host. Cuando se requiera contenido inseguro, se debe de considerar el alojarlo en un dominio inseguro separado.
Implementar HTTP Strict Transport Security (HSTS) para forzar el uso conexiones HTTPS.
Si quiere obtener más información sobre la implementación de TLS de forma segura, consulte este enlace.
Cookies
El mecanismo de intercambio de IDs de sesión basado en cookies proporciona múltiples características de seguridad en forma de atributos en las cookies que pueden usarse para proteger el intercambio del ID de sesión.
Atributo Secure
El atributo Secure de las cookies indica a los navegadores web que solo envíen la cookie a través de una conexión cifrada HTTPS (SSL/TLS). Este mecanismo de protección de sesión es obligatorio para evitar robos de ID de sesión a través de ataques MitM (Man-in-the-Middle). Se asegura de que un atacante no pueda capturar el ID de sesión del tráfico del navegador web.
Obligar a la aplicación web a que solo utilice HTTPS para su comunicación, incluso cuando el puerto TCP/80 (HTTP) está cerrado en el host de la aplicación web, no protege contra la divulgación del ID de sesión si no se ha configurado la cookie con el atributo Secure. El navegador web puede ser engañado para revelar el ID de la sesión a través de una conexión HTTP sin cifrar ya que el atacante puede interceptar y manipular el tráfico de red de la víctima e inyectar una referencia HTTP sin cifrar a la aplicación web que obligará al navegador web a enviar el ID de la sesión en texto plano.
Atributo HttpOnly
El atributo HttpOnly de las cookies indica a los navegadores web que no permitan que los scripts (por ejemplo, JavaScript o VBscript) puedan acceder a las cookies a través del objeto DOM document.cookie. Esta protección para los IDs de sesión es obligatoria para evitar el robo de IDs de sesión a través de ataques Cross Site Scripting (XSS).
Atributo SameSite
El atributo SameSite permite que un servidor defina un atributo que imposibilite al navegador enviar la cookie en solicitudes entre diferentes sitios web. El objetivo principal es mitigar el riesgo de fuga de información de origen cruzado y proporciona cierta protección contra ataques de falsificación de solicitudes en sitios cruzados, Cross-Site Request Forgery (CSRF).
Atributos Domain y Path
El atributo Domain de las cookies indica a los navegadores web que solo envíen la cookie al dominio especificado y a todos sus subdominios. Si no se establece el atributo, de manera predeterminada, la cookie solo se enviará al servidor de origen.
El atributo Path de las cookies indica a los navegadores web que solo envíen la cookie al directorio o subdirectorios (o rutas) especificados dentro de la aplicación web. Si no se establece el atributo, de manera predeterminada, la cookie solo se enviará para el directorio (o ruta) del recurso solicitado que está configurado en la cookie.
Se recomienda utilizar un alcance limitado o restringido para estos dos atributos. El atributo Domain no debe establecerse (restringiendo así la cookie al servidor de origen) y el atributo Path debe establecerse lo más restrictivo posible a la ruta de la aplicación web que utiliza el ID de sesión.
Establecer el atributo Domain en un valor demasiado permisivo, como http://example.com , permite que un atacante inicie ataques a los ID de sesión entre diferentes hosts y aplicaciones web que pertenecen al mismo dominio, conocidas como cookies de subdominio cruzado. Por ejemplo, las vulnerabilidades en http://www.example.com podrían permitir que un atacante obtenga acceso a los IDs de sesión desde secure.example.com.
También se recomienda no mezclar aplicaciones web de diferentes niveles de seguridad en el mismo dominio. Las vulnerabilidades en una de las aplicaciones web permitirían a un atacante establecer el ID de sesión para una aplicación web diferente en el mismo dominio mediante el uso de un atributo de Domain permisivo, la cual es una técnica que se utiliza en ataques de fijación de sesión.
Aunque el atributo Path permite el aislamiento de IDs de sesión entre diferentes aplicaciones web que utilizan diferentes rutas en el mismo host, se recomienda no ejecutar diferentes aplicaciones web (especialmente desde diferentes niveles de seguridad o ámbitos) en un mismo host ya que estas aplicaciones pueden utilizar métodos diferentes para acceder a los IDs de sesión. Además, cualquier aplicación web puede establecer cookies para cualquier ruta en ese host al estar compartido.
Las cookies son vulnerables a los ataques de DNS, donde un atacante puede manipular la resolución DNS para obligar al navegador web a revelar el ID de sesión para un host o dominio determinado.
Atributos Expire y Max-age
Los mecanismos de administración de sesión basados en cookies pueden utilizar dos tipos de cookies, cookies no persistentes (o de sesión) y cookies persistentes. Si una cookie presenta los atributos Max-Age (que tiene preferencia sobre Expire) o Expire, se considerará una cookie persistente y el navegador web la almacenará en el disco hasta el momento en el que caduque.
Normalemente, una de las capacidades de los sistemas de gestión de sesiones para rastrear a los usuarios después de la autenticación es hacer uso de cookies no persistentes. Esto obliga a que la sesión desaparezca del cliente si se cierra la instancia actual del navegador web. Por lo tanto, se recomienda utilizar, en la medida de lo posible, cookies no persistentes para fines de gestión de sesión, de modo que el ID de la sesión no permanezca en la memoria caché del cliente web durante largos períodos de tiempo, desde donde un atacante puede obtenerlo.
Se debe de asegurar que la información confidencial no esté comprendida, asegurándose de que la información confidencial: no sea persistente/esté cifrada/esté almacenada según sea necesario mientras sea necesario.
Se debe de asegurar que las operaciones no autorizadas no puedan realizarse mediante la manipulación de cookies.
Se debe de asegurar que esté configurado el atributo Secure para evitar la transmisión accidental por conexiones no seguras.
Se debe de asegurar que todas las transiciones de estado en el código de la aplicación verifican correctamente las cookies y hacen cumplir su uso.
Se debe de asegurar que toda la cookie está cifrada si persisten datos confidenciales en ella.
Explicar todas las cookies que utiliza la aplicación, su nombre y por qué son necesarias.
API Web Storage de HTML5
Las APIs localStorage y sessionStorage son mecanismos para almacenar pares nombre-valor del lado del cliente. A diferencia de las cookies HTTP, los contenidos de localStorage y sessionStorage no se comparten automáticamente entre las solicitudes o respuestas del navegador y se utilizan para almacenar datos en el lado del cliente.
API localstorage
Alcance
Los datos almacenados utilizando la API localStorage pueden ser accedidos mediante páginas cargadas desde el mismo origen (https:\\), host, puerto (443) y dominio. Esto proporciona un acceso similar a estos datos cómo haciéndolo a través del atributo Secure en una cookie, lo que significa que los datos almacenados desde https no se pudieron recuperar a través de http. Debido al posible acceso concurrente desde ventanas/subprocesos separados, los datos almacenados usando localStorage pueden ser susceptibles a problemas de acceso compartido y deben considerarse no bloqueantes.
Duración
Los datos almacenados utilizando la API localStorage se conservan en las sesiones de navegación, extendiendo el período de tiempo en el que pueden acceder otros usuarios del sistema.
Acceso sin conexión
Los estándares no requieren que los datos de localStorage se cifren, lo que significa que es posible acceder directamente a estos datos desde el disco duro.
Caso de uso
El Web Hypertext Application Technology Working Group (WHATWG) sugiere el uso de localStorage para datos a los que se debe acceder a través de ventanas o pestañas, a través de múltiples sesiones y donde grandes volúmenes de datos (de varios megabytes) pueden necesitar ser almacenados en el disco duro por razones de rendimiento.
API sessionStorage
Alcance
La API sessionStorage almacena datos dentro del contexto de la ventana desde la que se llamó, lo que significa que la pestaña 1 no puede acceder a los datos almacenados en la pestaña 2. Además, de la misma forma que la API localStorage, los datos almacenados usando sessionStorage es accesible desde el mismo origen, ya sea a través del esquema (https:\\), el host (ejemplo.com), el puerto (443) o el dominio (ejemplo.com).
Esto proporciona un acceso similar a los datos que usando el atributo Secure de las cookies, lo que significa que los datos almacenados desde HTTPS no se pueden obtener a través de HTTP.
Duración
La API sessionStorage solo almacena datos durante la sesión actual. Una vez que se cierra la pestaña, esos datos ya no se pueden recuperar. Esto no impide el acceso si una pestaña del navegador se reutiliza o se deja abierta. Además, los datos también pueden persistir en memoria hasta que se ejecute el recolector de basura.
Acceso sin conexión
Los estándares no requieren que los datos de sessionStorage se cifren, lo que significa que es posible acceder directamente a estos datos desde el disco duro.
Caso de uso
El Web Hypertext Application Technology Working Group (WHATWG) sugiere el uso de sessionStorage para los datos que son relevantes en una instancia de un flujo de trabajo. Un ejemplo son los detalles para la reserva de un ticket donde se pueden realizar múltiples flujos de trabajo en otras pestañas al mismo tiempo. Al estar vinculados los datos a la ventana/pestaña evitará que se filtren entre flujos de trabajo en pestañas diferentes.
Riesgos de seguridad
En general, todo dato seguro o confidencial no debe de almacenarse de forma persistente usando los mecanismos de almacenamiento del navegador, ya que esto puede permitir la filtración de información en sistemas compartidos. Debido a que los mecanismos de almacenamiento de los navegadores web son APIs, esto permite el acceso desde scripts embebidos, lo que lo hace menos seguro que usar cookies con el atributo HttpOnly habilitado.
Las APIs de los mecanismos de almacenamiento de navegadores web deben de tratarse como un almacenamiento inseguro. Si una solución comercial requiere el uso de localStorage o sessionStorage para almacenar datos confidenciales, dicha solución debería cifrar datos y aplicar las protecciones oportunas. Debido a la posibilidad de acceder a las API de almacenamiento web a través de un ataque XSS, los identificadores de sesión deben almacenarse utilizando cookies no persistentes, con los indicadores apropiados para proteger contra el acceso inseguro (Secure), XSS (HttpOnly) y problemas CSRF (SameSite).
Ciclo de vida de un ID de sesión
Generación y verificación de IDs de sesión: gestión de sesión permisiva y gestión de sesión estricta
Existen dos tipos de mecanismos de administración de sesión para las aplicaciones web (permisivos y estrictos) relacionados con las vulnerabilidades de fijación de sesión.
Permisivos: Permiten que la aplicación web acepte por defecto cualquier valor de ID de sesión establecido por el usuario como válido, creando una nueva sesión para él.
Estrictos: Exigen que la aplicación web solo acepte valores de ID de sesión que hayan sido generados previamente por la aplicación web.
Los tokens de sesión deben de ser manejados por el servidor web si es posible o generarse a través de un generador de números aleatorios criptográficamente seguro.
A pesar de que el mecanismo mas común es el estricto, los desarrolladores deben de asegurarse de que la aplicación web no utilice un mecanismo permisivo bajo ciertas circunstancias. Las aplicaciones web nunca deben aceptar un ID de sesión que nunca hayan generado y en caso de recibir uno, deben de generar y ofrecer al usuario un nuevo ID de sesión válido Además, este escenario se debe de tratar como una actividad sospechosa y se debe de generar una alerta.
Administrar IDs de sesión como cualquier otra entrada de usuario
Los IDs de sesión deben de considerarse no confiables, como cualquier otra entrada de usuario procesada por la aplicación web y deben tanto validarse como verificarse exhaustivamente. Dependiendo del mecanismo de gestión de sesión utilizado, los IDs de sesión se recibirán en un parámetro GET o POST, en la URL o en una cabecera HTTP de una cookie. Si las aplicaciones web no validan y filtran los valores de ID de sesión no válidos antes de procesarlos, pueden utilizarse para explotar otras vulnerabilidades como la inyección de SQL si los IDs de sesión se almacenan en una base de datos relacional o XSS persistente si los IDs de sesión son almacenados y mostrados posteriormente por la aplicación web.
Renovar el ID de sesión después de cualquier cambio de nivel de privilegios
La aplicación web debe renovar o regenerar el ID de sesión después de cualquier cambio de nivel de privilegios ocurrido durante la sesión actual asociada al usuario. El escenario más común donde la regeneración de ID de sesión es obligatorio es durante el proceso de autenticación, ya que el nivel de privilegio del usuario cambia del estado no autenticado al estado autenticado. También se deben de considerar otros escenarios comunes como cambios de contraseña, cambios de permisos o cambio de un rol de usuario normal a un rol de administrador dentro de la aplicación web. Para todas estas páginas críticas de aplicaciones web, se deben de ignorar los IDs de sesión anteriores asignando un nuevo ID de sesión a cada nueva solicitud recibida para el recurso crítico y se debe de destruir el ID de sesión anterior o antiguo.
Los frameworks web más utilizados ya proporcionan funciones y métodos para renovar los IDs de sesión.
Consideraciones al usar múltiples cookies
Si la aplicación web utiliza cookies como mecanismo de intercambio de IDs de sesión y se configuran varias cookies para una sesión determinada, la aplicación web debe verificar todas las cookies (y hacer cumplir las relaciones entre ellas) antes de generar la sesión del usuario.
Es muy común que las aplicaciones web establezcan una autenticación previa de cookies a través de HTTP para realizar un seguimiento de usuarios no autenticados. Una vez que el usuario se autentica en la aplicación web, se establece una nueva cookie segura posterior a la autenticación a través de HTTPS y se establece un enlace entre ambas cookies y la sesión del usuario. Si la aplicación web no verifica ambas cookies para las sesiones autenticadas, un atacante puede hacer uso de la cookie no protegida previa a la autenticación para obtener acceso a la sesión del usuario autenticado.
Las aplicaciones web deben tratar de evitar el mismo nombre de cookie para diferentes rutas o dominio/subdominios dentro de la misma aplicación web, ya que esto aumenta la complejidad de la solución e introduce problemas potenciales de alcance.
Caducidad de la sesión
Para minimizar el período de tiempo en el que un atacante puede lanzar ataques sobre sesiones activas y secuestrarlas, es obligatorio establecer tiempos caducidad para cada sesión estableciendo la cantidad de tiempo que una sesión permanecerá activa. Un tiempo de caducidad de sesión insuficiente por parte de la aplicación web aumenta la exposición de ataques basados en la sesión, ya que para que el atacante pueda reutilizar un ID de sesión válido y secuestrar la sesión asociada esta aún debe de estar activa.
Cuanto más corta se la duración de la sesión, menor será el tiempo que un atacante tiene para usar el ID de sesión válido. Los valores caducidad de la sesión deben establecerse de acuerdo con el propósito y la naturaleza de la aplicación web equilibrando seguridad y usabilidad, para que el usuario pueda completar las operaciones en la aplicación web sin que su sesión caduque durante el proceso.
Los valores de tiempo de caducidad dependen en gran medida de la importancia de la aplicación web y sus datos. Los intervalos de caducidad comunes son de 2-5 minutos para aplicaciones de alto riesgo y de 15-30 minutos para aplicaciones de bajo riesgo.
Cuando una sesión caduca, la aplicación web debe tomar las acciones necesarias para invalidar la sesión en ambos lados, cliente y servidor. Este último es el más relevante y obligatorio desde una perspectiva de seguridad.
Para la mayoría de los mecanismos de intercambio de sesiones, las acciones del lado del cliente para invalidar el ID de la sesión se basan en borrar el valor del token. Por ejemplo, para invalidar una cookie, se recomienda proporcionar un valor vacío (o no válido) para el ID de sesión y establecer el atributo Expires(o Max-Age) en una fecha del pasado (en caso de que se use una cookie persistente).
Para cerrar e invalidar la sesión en el lado del servidor, es obligatorio que la aplicación web tome las acciones necesarias cuando la sesión caduque o el usuario cierre sesión activamente, utilizando las funciones y métodos ofrecidos por los mecanismos de administración de sesión que proporcionen los frameworks utilizados.
Caducidad de sesión automática
Tiempo de inactividad
Todas las sesiones deben implementar un tiempo de inactividad. Este tiempo de espera define la cantidad de tiempo que una sesión permanecerá activa en caso de que no haya actividad en la sesión, cerrando e invalidando la sesión en el período inactivo definido desde la última solicitud HTTP recibida por la aplicación web para un ID de sesión dado.
El tiempo de inactividad limita las posibilidades de que un atacante tenga que adivinar y usar un ID de sesión válido de otro usuario. Sin embargo, si el atacante puede secuestrar una sesión determinada, el tiempo de inactividad no limita las acciones del atacante ya que puede generar actividad en la sesión periódicamente para mantenerla activa durante períodos más largos.
La gestión del tiempo de espera y la caducidad de la sesión deben de aplicarse en el lado del servidor. Si el cliente se usa para imponer el tiempo de espera de la sesión un atacante podría manipularlas para extender la duración de la sesión.
Tiempo de espera absoluto
Todas las sesiones deben implementar un tiempo de espera absoluto independientemente de la actividad de la sesión. Este tiempo de espera define la cantidad máxima de tiempo que una sesión puede estar activa, cerrando e invalidando la sesión en el período absoluto definido desde que la aplicación web creó inicialmente dicha sesión. Después de invalidar la sesión, el usuario se ve obligado a (re)autenticarse de nuevo en la aplicación web estableciendo así una nueva sesión.
La sesión absoluta limita la cantidad de tiempo que un atacante puede usar una sesión secuestrada y hacerse pasar por un usuario víctima.
Renovación del tiempo de espera
De forma alternativa la aplicación web puede implementar un tiempo de espera de renovación adicional después del cual el ID de la sesión se renueve automáticamente, en medio de la sesión del usuario e independientemente de la actividad de la sesión y del tiempo de espera inactivo.
Después de un período de tiempo específico desde que se creó la sesión, la aplicación web puede regenerar un nuevo ID para la sesión e intentar establecerla o renovarla en el cliente. El valor del ID de sesión anterior seguiría siendo válido durante un intervalo de seguridad antes de que el cliente conozca el nuevo ID y comience a usarlo. En ese momento, cuando el cliente cambia al nuevo ID dentro de la sesión actual, la aplicación invalida el ID anterior.
Este escenario minimiza la cantidad de tiempo que un valor de ID de sesión, potencialmente obtenido por un atacante, puede reutilizarse para secuestrar la sesión del usuario incluso cuando la sesión del usuario víctima todavía está activa. La sesión del usuario permanece siendo válida en el cliente legítimo aunque el valor de ID de sesión asociado se renueve de forma periódica durante la duración de la misma cada vez que expira el tiempo de renovación. Por lo tanto, el tiempo de espera de renovación complementa los tiempos de espera de inactividad y absolutos, especialmente cuando el valor de tiempo de espera absoluto se extiende de forma significativa a lo largo del tiempo.
Dependiendo de la implementación podría haber una condición en la que el atacante con un ID de sesión anterior que aún sea válido envíe una solicitud antes del usuario víctima, justo después de que el tiempo de espera de renovación haya expirado y obtenga primero el valor del ID de sesión renovado. En este escenario el usuario víctima podría ser consciente del ataque, ya que su sesión finalizará repentinamente porque su ID de sesión asociado ya no es válido.
Caducidad de sesión manual
Las aplicaciones web deben de proporcionar mecanismos que permitan a los usuarios que son conscientes de la seguridad, cerrar activamente su sesión una vez que hayan terminado de usar la aplicación web.
Botón de cerrar sesión
Las aplicaciones web deben proporcionar un botón de cierre de sesión visible y de fácil acceso que esté disponible en la cabecera o menú de la aplicación web y al que se pueda acceder desde cada recurso y página de la aplicación web, permitiendo al usuario poder cerrar la sesión de forma manual en en cualquier momento. Tal y como se describe en la sección anterior, la aplicación web debe invalidar la sesión al menos en el lado del servidor.
Por desgracia, no todas las aplicaciones web facilitan a los usuarios el poder cerrar su sesión actual. Las mejoras del lado del cliente permiten a los usuarios conscientes de su seguridad proteger sus sesiones al facilitarles la posibilidad de cerrarlas.
Almacenamiento en caché de contenido web
Incluso después de que se haya cerrado la sesión es posible acceder a los datos privados o confidenciales intercambiados dentro de la sesión a través de la memoria caché del navegador web. Por lo tanto, las aplicaciones web deben usar directivas de caché restrictivas para todo el tráfico web intercambiado a través de HTTP y HTTPS, como las cabeceras HTTP de Cache-Control y Pragma, y/o las etiquetas META equivalentes en todas las páginas web sensibles.
Independientemente de la política de caché definida por la aplicación web, si se permite el almacenamiento en caché del contenido de la aplicación web los ID de sesión nunca deben de almacenarse, por lo que se recomienda utilizar la directiva Cache-Control: no-cache="Set-Cookie, Set-Cookie2, etc." para permitir que los clientes web almacenen en caché todo excepto el ID de sesión.
Defensas adicionales del lado del cliente para la gestión de sesiones
Las aplicaciones web pueden complementar las defensas de administración de sesiones descritas anteriormente con contramedidas adicionales en el lado del cliente. Las protecciones del lado del cliente, generalmente en forma de comprobaciones y verificaciones de JavaScript, no son a definitivas y pueden ser fácilmente superadas por un atacante experto, pero pueden introducir otra capa de defensa que los intrusos deben evitar.
Tiempo de espera inicial antes del inicio de sesión
Las aplicaciones web pueden usar el código JavaScript en la página de inicio de sesión para evaluar y medir la cantidad de tiempo desde que se cargó la página y se otorgó un ID de sesión. Si se intenta un intento de inicio de sesión después de un período de tiempo específico, el código del cliente puede notificar al usuario que ha pasado el tiempo máximo para iniciar sesión y volver a cargar la página de inicio de sesión, recuperando así un nuevo ID de sesión.
Este mecanismo de protección adicional intenta forzar la renovación de la autenticación previa de ID de sesión, evitando escenarios en los que un ID de sesión utilizado previamente (o configurado manualmente) es reutilizado por la siguiente víctima en el mismo ordenador, por ejemplo, en ataques de fijación de sesión.
Forzar el cierre de sesión en los eventos de cierre de ventanas/pestañas del navegador web
Las aplicaciones web pueden usar el código JavaScript para capturar todos los eventos de cierre de ventana o pestaña del navegador web y tomar las medidas apropiadas para cerrar la sesión actual antes de cerrar el navegador web, emulando que el usuario ha cerrado manualmente la sesión a través del cierre de sesión botón.
Deshabilitar las sesiones en varias pestañas en los navegadores web
Las aplicaciones web pueden usar el código JavaScript una vez que el usuario ha iniciado sesión y se ha establecido una sesión para olbigar a volver a autenticarse si se abre una nueva pestaña o ventana del navegador web en la misma aplicación web. La aplicación web no debe permitir que múltiples pestañas o ventanas del navegador compartan una misma sesión. Por lo tanto, la aplicación intentará forzar al navegador web a no compartir el misma ID de sesión simultáneamente entre ellas.
Sin embargo, este mecanismo no se puede implementar si el ID de sesión se intercambia a través de cookies ya que las cookies se comparten en todas las pestañas/ventanas del navegador web.
Cierre de sesión automático del cliente
La aplicación web puede usar el código JavaScript en todas las páginas (o solo en las críticas) para cerrar la sesión automáticamente en las sesiones del cliente después de que caduque el tiempo de inactividad, redirigiendo al usuario a la página de cierre de sesión.
El beneficio de mejorar la funcionalidad de tiempo de espera inactivo del lado del servidor con el código del lado del cliente es que el usuario puede ver que la sesión ha finalizado debido a la inactividad o incluso puede recibir una notificación por adelantado de que la sesión está a punto de expirar. Este enfoque fácil de usar ayuda a evitar la pérdida de trabajo en páginas web que requieren datos de entrada extensos debido a sesiones caducadas silenciosamente en el lado del servidor. Este enfoque amigable para el usuario evita la pérdida de trabajo en aplicaciones de entrada de datos masivos en las que no se ha guardado aún los cambios realizados y de forma silenciosa la sesión ha caducado en el lado servidor.
Detección de ataques de sesión
Detección de ataques de fuerza bruta y predicción de IDs de sesión
Si un atacante intenta adivinar o forzar por fuerza bruta un ID de sesión válido, necesita lanzar múltiples solicitudes secuenciales contra la aplicación web de destino utilizando diferentes IDs de sesión desde una o un conjunto de direcciones IP. Además, si un atacante intenta analizar la predicción de IDs de sesión debe lanzar múltiples solicitudes secuenciales desde una o un conjunto de direcciones IP contra la aplicación web de destino para obtener nuevos IDs de sesión válidos.
Las aplicaciones web deben de poder detectar ambos escenarios en función del número de intentos de recopilación (o uso) de diferentes IDs de sesión y alertar y/o bloquear las direcciones IP involucradas.
Detección de anomalías de IDs de sesión
Las aplicaciones web deberían de centrarse en detectar anomalías asociadas a los IDs de sesión, como la manipulación de IDs.
Enlazar el ID de sesión a otras propiedades de usuario
Con el objetivo de detectar y proteger los malos comportamientos de los usuarios y el secuestro de sesiones, se recomienda vincular el ID de la sesión a otras propiedades del usuario o del cliente. Si la aplicación web detecta algún cambio o anomalía entre las diferentes propiedades mientras establece una sesión, es un muy buen indicador de la manipulación de la sesión e intentos de secuestro. Este simple hecho puede usarse para alertar y/o finalizar la sesión sospechosa.
Aunque estas propiedades no pueden ser usadas por las aplicaciones web para defenderse con certeza de los ataques de sesión, aumentan significativamente las capacidades de detección y protección. Sin embargo, un atacante experto puede omitir estos controles reutilizando la misma dirección IP asignada al usuario víctima compartiendo la misma red, utilizando el mismo proxy web saliente o modificando manualmente su User-Agent para que se vea exactamente como lo hacen los usuarios víctimas.
Ciclo de vida de los registros de sesiones: Monitorización de creación, uso y destrucción del ID de sesión
Las aplicaciones web deberían aumentar sus capacidades de registro al incluir información sobre el ciclo de vida completo de las sesiones. En particular, se recomienda registrar eventos relacionados con la sesión como la creación, renovación y destrucción de ID de sesión, así como detalles sobre su uso dentro de las operaciones de inicio y cierre de sesión, cambios de nivel de privilegios dentro de la sesión, vencimiento del tiempo de espera, actividades no válidas (cuando se detectan) y operaciones críticas durante la sesión.
Los detalles de los registros pueden incluir una marca de tiempo, una dirección IP de origen, el recurso de destino web solicitado, cabeceras HTTP, parámetros GET y POST, códigos y mensajes de error, nombre de usuario (o ID de usuario), etc.
Los datos confidenciales como el ID de sesión no deben de incluirse en los registros para protegerlos contra la divulgación local o remota de información o el acceso no autorizado. Sin embargo, se debe registrar algún tipo de información específica de la sesión para correlacionar las entradas de registro con sesiones específicas. Se recomienda registrar un hash con salto del ID de sesión en lugar del ID de sesión en sí para permitir la correlación específica de la sesión sin exponer el ID de sesión.
En particular, las aplicaciones web deben proteger a fondo las interfaces administrativas que permiten administrar todas las sesiones activas en curso. Con frecuencia, estos son utilizados por el personal de soporte para resolver problemas relacionados con la sesión, o incluso problemas generales, suplantando al usuario y mirando la aplicación web como lo hace el usuario.
Los registros de sesión se convierten en una de las principales fuentes de datos de detección de intrusos de aplicaciones web y también pueden ser utilizados por los sistemas de protección contra intrusos para finalizar automáticamente las sesiones y/o deshabilitar las cuentas de usuario cuando se detectan ataques. Si se implementan protecciones activas, estas acciones defensivas también deben registrarse.
Inicios de sesión simultáneos
A la hora de diseñar la aplicación web se debe de determinar si se permiten múltiples inicios de sesión simultáneos del mismo usuario desde la misma o desde diferentes direcciones IP del cliente. Si la aplicación web no desea permitir inicios de sesión simultáneos, debe de realizar acciones efectivas después de cada nuevo evento de autenticación, ya sea finalizando implícitamente la sesión disponible anteriormente o preguntar al usuario sobre la sesión que debe permanecer en activo.
Se recomienda que las aplicaciones web incluyan opciones al usuario que permitan verificar los detalles de las sesiones activas en cualquier momento, monitorear y alertar al usuario sobre inicios de sesión concurrentes, proporcionar funciones de usuario para finalizar sesiones de forma remota manualmente y rastrear el historial de actividad de la cuenta mediante el registro de múltiples detalles del cliente para cada sesión.
Sistemas de protección WAF en la gestión de sesiones
Hay situaciones en las que el código fuente de la aplicación web no está disponible, no se puede modificar, los cambios necesarios para implementar las múltiples recomendaciones de seguridad y las mejores prácticas detalladas anteriormente implican un rediseño completo de la arquitectura de la aplicación web y, por lo tanto, no se pueden implementar fácilmente a corto plazo.
En estos escenarios, o para complementar las defensas de la aplicación web, y con el objetivo de mantener la aplicación web lo más segura posible, se recomienda utilizar protecciones externas como los firewalls de aplicaciones web (WAF) que pueden mitigar las amenazas de administración de sesión ya descritas.
Los firewalls de aplicaciones web ofrecen capacidades de detección y protección contra ataques basados en sesiones. Por un lado, es trivial que los WAF impongan el uso de atributos de seguridad en las cookies, como los indicadores Secure y HttpOnly, aplicando reglas básicas de reescritura en la cabecera Set-Cookie para todas las respuestas de la aplicación web que establecen una nueva cookie.
Por otro lado, se pueden implementar capacidades más avanzadas para permitir que el WAF realice un seguimiento de las sesiones y los ID de sesión correspondientes y aplique todo tipo de protecciones contra la fijación de la sesión (renovando la ID de la sesión en el lado del cliente cuando cambia se detecta un cambio de privilegios), imponiendo sesiones fijas (verificando la relación entre el ID de la sesión y otras propiedades del cliente), o administrando la caducidad de la sesión (obligando tanto al cliente como a la aplicación web a finalizar la sesión).
El WAF, de código libre, ModSecurity y el conjunto de reglas básicas de OWASP proporcionan capacidades para detectar y aplicar atributos de cookies de seguridad, contramedidas contra ataques de fijación de sesión y características de seguimiento de sesión para imponer sesiones fijas.