Cuando un usuario se autentica en el sistema y obtiene la autorización en el mismo, se crea una nueva sesión identificada mediante un id, la cual crea una conexión activa usuario-sistema, almacenando información temporal sobre las operaciones y la lógica de negocio exclusivas de ese usuario mientras dure dicha sesión.
Imagen: Wallpaperflare
Una vez establecida la sesión, para poder llevar a cabo las operaciones, el usuario se identificará con el servidor mediante cookies o mediante tokens. En el caso de las cookies, éstas se almacenan en el navegador del cliente, lo que es un sistema poco seguro y no recomendable. Los tokens, sin embargo, se asocian al id de la sesión y viajan en la cabecera de las peticiones, y pueden modificarse por intercambio cada cierto tiempo sin necesidad de cambiar el id de la sesión, la cual permanece en el lado del servidor, lo que es un método mucho más seguro que el de las cookies.
Aspectos de seguridad
Aspectos básicos
- Asegurar que la autenticación sólo permite acceder a las personas acreditadas.
- Asegurar las autorizaciones correctas para las personas autenticadas.
- Asegurar la comunicación cliente-servidor mediante cifrado fuerte.
Sesión del lado cliente
- La información persistente del id de sesión del cliente quedará asociada a la pestaña, y si ésta se cierra o desaparece, desaparecerá toda esa información. Esto se logra mediante código en la propia página o mediante el objeto sessionStorage.
- La información persistente de la sesión del cliente se ha de borrar en la pantalla de login y generarse una vez creada la sesión en el servidor.
- En pantallas que puedan necesitar mucho tiempo (por ejemplo, un formulario), permitir que la sesión de cliente realice transacciones vacías contra el servidor, para indicar que la sesión sigue activa y no expire.
- El cliente también debe controlar el tiempo de inactividad, lanzando una petición al servidor para que cierre la sesión, tras lo cual se redirigirá a la pantalla de login.
- La información de la sesión del cliente ha de ser mínima para la lógica de navegación. No debe contener información sensible. A lo sumo, puede contener el token de acceso para no arrastrarlo en todas las peticiones.
- Evitar ataques de fijación de sesión mediante un tiempo de espera de inicio de sesión.
- Capturar los eventos de cierre de pestaña o de la ventana del navegador, a fin de forzar tanto el cierre de la sesión de cliente como del servidor.
ID de sesión
- El id de sesión ha de ser único, aleatorio y con una longitud muy grande, como un hash criptográfico seguro.
- El id ha de ser validado por el servidor, verificando su formato y que está presente en una sesión válida y activa.
- En los registros no usar nunca el id de sesión.
- Para evitar ataques de fijación de sesión, cambiar el id de sesión en cada inicio de sesión o en un cambio de privilegios de usuario.
- Al monitorizar y almacenar los ids de sesión activos, asegurarse de que no pueden ser consultados por usuarios no autorizados.
Cierre de sesión
- Redirección a la pantalla de login en cada cierre.
- Eliminación de toda la información de la cookie o del token de acceso.
- Eliminación de toda la información de la sesión cliente.
- Registro del cierre (registro de seguridad).
Caducidad de la sesión
- Definir un tiempo máximo de vida, para que no esté permanentemente activa.
- Definir un tiempo máximo absoluto de duración para la sesión.
- Toda la información de la sesión debe eliminarse del servidor cuando caduca.
- Registrar (registro de seguridad) cada vez que una sesión expira.
- Usar tokens, con el fin de que no sean usados en caso de que el dispositivo se pierda o se sustraiga.
- El token de sesión no puede contener el id del dispositivo.
- La caducidad de la sesión ha de configurarse según la sensibilidad de la app.
- Para utilizar la sesión en varias páginas apoyarse en un repositorio de datos basado en servidor.
Posibles riesgos
A continuación se describen algunos de los posibles riesgos relativos a la gestión de sesiones:
- Predicción de sesión. El id de sesión podría adivinarse y así evitar la autenticación.
- Secuestro de sesión. Aprovecha el mecanismos de control de la sesión web, normalmente mediante un token de sesión.
- Fijación de sesión. Mediante la obtención de un id de sesión correcto, permitiría a un usuario autenticarse y secuestrar la sesión.
- Suplantación de sesión. Ejemplo: mediante phishing, se engaña a una víctima para entrar en un sitio web malicioso que suplante un sitio legítimo.
Mejores prácticas
- El id de sesión nunca debe exponerse bajo tráfico no cifrado.
- Implementar cabeceras seguras, como strict-transport security ó cache-control.
- La sesión ha de expirar pasado un tiempo de inactividad.
- Las páginas que necesiten autenticación han de tener la opción de cierre de sesión.
- El id de sesión nunca debe aparecer en urls, registros o mensajes de error.
- Cada autenticación y re-autenticación ha de destruir la sesión anterior y crear una nueva.
- El id de sesión almacenado en cookies se define mediante los atributos HttpOnly y Secure.
- Para evitar el acceso a otros dominios, configurar el atributo Path de las cookies.
- La aplicación debe realizar seguimiento de las sesiones activas, así como permitir al usuario finalizar éstas de forma selectiva o global desde su cuenta.
- Al cambiar una contraseña, se deben cerrar todas las sesiones activas.
- Asegurarse de que sólo los usuarios autorizados acceden a recursos protegidos: urls, funciones, datos de la aplicación, atributos de usuario y datos de configuración de acceso.
- Registrar (registro de seguridad) todas la actividades (o eventos) de las sesiones, tanto del cliente como del servidor.