La autenticación y gestión de sesiones incluye todos los aspectos de manejo de la autenticación de usuario y la gestión de sesiones activas. La autenticación es un aspecto crítico de este proceso, pero incluso los mecanismos sólidos de autenticación pueden ser socavados por funciones defectuosas de gestión de credenciales, incluyendo el cambio de contraseña, olvidé mi contraseña, recordar mi contraseña, actualización de cuenta, y otras funciones relacionadas. Debido a que los ataques “al paso” son probables en muchas aplicaciones web, todas las funciones de gestión de cuentas deben requerir reautenticación incluso si el usuario tiene un id de sesión válido.
La autenticación de usuarios en la web normalmente involucra el uso de un ID de usuario y una contraseña. Existen métodos más fuertes de autenticación comercialmente disponibles, como tokens criptográficos basados en software y hardware o biometría, pero estos mecanismos son costosos para la mayoría de las aplicaciones web. Un amplio rango de fallas en la gestión de cuentas y sesiones puede resultar en el compromiso de cuentas de usuario o administración de sistemas. Los equipos de desarrollo frecuentemente subestiman la complejidad de diseñar un esquema de autenticación y gestión de sesiones que proteja adecuadamente las credenciales en todos los aspectos del sitio. Las aplicaciones web deben establecer sesiones para seguir el rastro de las solicitudes de cada usuario. HTTP no proporciona esta capacidad, por lo que las aplicaciones web deben crearla ellas mismas. Frecuentemente, el entorno de la aplicación web proporciona una capacidad de sesión, pero muchos desarrolladores prefieren crear sus propios tokens de sesión. En cualquier caso, si los tokens de sesión no están debidamente protegidos, un atacante puede secuestrar una sesión activa y asumir la identidad de un usuario. Crear un esquema para crear tokens de sesión fuertes y protegerlos a lo largo de su ciclo de vida ha demostrado ser esquivo para muchos desarrolladores. A menos que todas las credenciales de autenticación y los identificadores de sesión estén protegidos con SSL en todo momento y protegidos contra la divulgación de otras fallas, como el scripting entre sitios, un atacante puede secuestrar la sesión de un usuario y asumir su identidad.
Solución
El uso cuidadoso y adecuado de mecanismos de autenticación y gestión de sesiones personalizados o de serie debería reducir significativamente la probabilidad de un problema en esta área. Definir y documentar la política de su sitio con respecto a la gestión segura de las credenciales de los usuarios es un buen primer paso. Asegurarse de que su implementación cumple consistentemente esta política es clave para tener un mecanismo de autenticación y gestión de sesiones seguro y robusto. Algunas áreas críticas incluyen:
- Fortaleza de la Contraseña – las contraseñas deberían tener restricciones que requieran un tamaño y complejidad mínimos para la contraseña. La complejidad típicamente requiere el uso de combinaciones mínimas de caracteres alfabéticos, numéricos y/o no alfanuméricos en la contraseña del usuario (p. ej., al menos uno de cada tipo). Los usuarios deberían ser requeridos a cambiar su contraseña periódicamente. Los usuarios deberían ser prevenidos de reusar contraseñas previas.
- Uso de la Contraseña – Los usuarios deberían ser restringidos a un número definido de intentos de inicio de sesión por unidad de tiempo y los intentos de inicio de sesión fallidos deberían ser registrados. Las contraseñas proporcionadas durante intentos de inicio de sesión fallidos no deberían ser grabadas, ya que esto puede exponer la contraseña de un usuario a quien pueda obtener acceso a este registro. El sistema no debería indicar si fue el nombre de usuario o la contraseña lo que estuvo mal si un intento de inicio de sesión falla. Los usuarios deberían ser informados de la fecha/hora de su último inicio de sesión exitoso y el número de intentos fallidos de acceso a su cuenta desde esa vez.
- Controles de Cambio de Contraseña – Un único mecanismo de cambio de contraseña debería ser usado dondequiera que se permita a los usuarios cambiar una contraseña, sin importar la situación. Los usuarios siempre deberían ser requeridos a proporcionar tanto su vieja como su nueva contraseña al cambiar su contraseña (como toda la información de cuenta). Si las contraseñas olvidadas son enviadas por correo electrónico a los usuarios, el sistema debería requerir al usuario que se reautentifique siempre que el usuario esté cambiando su dirección de correo electrónico, de lo contrario un atacante que temporalmente tiene acceso a su sesión (p. ej., acercándose a su computadora mientras están conectados) simplemente puede cambiar su dirección de correo electrónico y solicitar que una contraseña ‘olvidada’ les sea enviada.
- Almacenamiento de Contraseña – Todas las contraseñas deben ser almacenadas en forma encriptada o hasheada para protegerlas de la exposición, sin importar dónde estén almacenadas. La forma hasheada es preferida ya que no es reversible. La encriptación debería ser usada cuando se necesita la contraseña en texto plano, como por ejemplo cuando se usa la contraseña para iniciar sesión en otro sistema. Las contraseñas nunca deberían ser codificadas en el código fuente. Las claves de descifrado deben ser fuertemente protegidas para asegurar que no puedan ser capturadas y usadas para descifrar el archivo de contraseñas.
- Protección de Credenciales en Tránsito – La única técnica efectiva es encriptar la transacción de inicio de sesión completa usando algo como SSL. Las transformaciones simples de la contraseña como hashearla en el cliente antes de la transmisión proporcionan poca protección ya que la versión hasheada simplemente puede ser interceptada y retransmitida aunque la contraseña en texto plano real no se conozca.
- Protección de ID de Sesión – Idealmente, toda la sesión de un usuario debería ser protegida vía SSL. Si esto se hace, entonces el ID de sesión (p. ej., cookie de sesión) no puede ser capturado en la red, que es el mayor riesgo de exposición para un ID de sesión. Si SSL no es viable por rendimiento u otras razones entonces los propios IDs de sesión deben ser protegidos de otras maneras. Primero, nunca deberían ser incluidos en la URL ya que pueden ser almacenados en caché por el navegador, enviados en el encabezado de referrer, o accidentalmente reenviados a un ‘amigo’. Los IDs de sesión deberían ser números largos, complicados y aleatorios que no puedan ser fácilmente adivinados. Los IDs de sesión también pueden ser cambiados frecuentemente durante una sesión para reducir el tiempo de validez de un ID de sesión. Los IDs de sesión deben ser cambiados cuando se cambia a SSL, autenticación, u otras transiciones importantes. Nunca se debería aceptar un ID de sesión elegido por un usuario.
- Listas de Cuentas – Los sistemas deberían ser diseñados para evitar permitir que los usuarios obtengan acceso a una lista de los nombres de cuenta en el sitio. Si se deben presentar listas de usuarios, se recomienda que se liste alguna forma de pseudónimo (nombre de pantalla) que mapee a la cuenta real en lugar de ello. De esta manera, el pseudónimo no puede ser usado durante un intento de inicio de sesión u otro hackeo que vaya tras la cuenta de un usuario.
- Almacenamiento en Caché del Navegador – Los datos de autenticación y sesión nunca deberían ser enviados como parte de un GET, siempre se debería usar POST en su lugar. Las páginas de autenticación deberían ser marcadas con todas las variantes de la etiqueta de no almacenar en caché para evitar que alguien use el botón de retroceso en el navegador de un usuario para regresar a la página de inicio de sesión y reenviar las credenciales previamente ingresadas. Muchos navegadores ahora soportan la bandera AUTOCOMPLETE=OFF para prevenir el almacenamiento de credenciales en cachés de autocompletado.
- Relaciones de Confianza – La arquitectura de su sitio debería evitar la confianza implícita entre componentes siempre que sea posible. Cada componente debería autenticarse a cualquier otro componente con el que esté interactuando a menos que haya una razón fuerte para no hacerlo (como rendimiento o falta de un mecanismo utilizable). Si se requieren relaciones de confianza, deberían existir fuertes mecanismos procedimentales y de arquitectura en su lugar para asegurar que dicha confianza no pueda ser abusada a medida que la arquitectura del sitio evoluciona con el tiempo.
Para un escaneo completo de vulnerabilidades y protección, considera asociarte con una solución confiable como INFRA (www.infrascan.net). INFRA ofrece un escaneo de seguridad avanzado con check.website y servicios de monitoreo para identificar todas las vulnerabilidades, garantizando la robustez de tus aplicaciones web.