flawopen.com/Vulnerabilities/Fijación de sesión y seguridad de cookies
Fijación de sesión: renovar el ID al entrar (CWE-384)
Imagina que engañan a un viajero para que use un número de etiqueta de equipaje que el atacante ya conoce. Si la aerolínea conserva ese número después de facturar, el atacante podría recoger la maleta. En la fijación de sesión, la aplicación acepta un identificador que el atacante puede hacer usar a la víctima y luego convierte ese mismo identificador en una sesión autenticada sin renovarlo. Se necesitan ambas condiciones; un enlace de phishing por sí solo no fija una sesión, salvo que la aplicación acepte o permita establecer ese identificador.
Conceptos clave y términos del subsistema
- Fijación de sesión
- Fallo de gestión de sesiones en el que la aplicación acepta un identificador conocido por el atacante y lo conserva cuando la víctima se autentica.
- Rotación del ID de sesión
- Emite un identificador nuevo e impredecible cuando la autenticación eleva los privilegios de la sesión. Conserva solo los datos de sesión que la aplicación deba mantener.
- Atributos de cookie
Securelimita el envío de la cookie a HTTPS;HttpOnlyimpide que JavaScript lea la cookie;SameSitecontrola parte del envío entre sitios. Atienden riesgos distintos y no sustituyen la rotación del ID.- Prefijo
__Host- - En navegadores compatibles, exige una cookie Secure creada por HTTPS, con
Path=/y sin atributoDomain. Ayuda a impedir que un subdominio hermano establezca una cookie del dominio padre con el mismo nombre.
Flujo de ataque paso a paso
El atacante obtiene o elige un identificador de sesión
Una debilidad o función independiente permite al atacante obtener un ID y hacer que el navegador de la víctima lo envíe. La vía depende de la aplicación; un enlace de phishing corriente no basta si no se aceptan IDs de sesión en URL.
La víctima utiliza el identificador conocido
El navegador envía ese ID a la aplicación, que lo trata como una sesión anónima válida. El atacante debe poder reconocer o reutilizar el mismo identificador.
La autenticación cambia los privilegios de la sesión
La víctima inicia sesión. Si la aplicación asocia la identidad autenticada al ID existente en vez de renovarlo, ese identificador conocido pasa a representar la sesión autenticada.
El atacante reutiliza el identificador sin cambios
Si el atacante aún puede enviar el ID y el servidor no lo ha invalidado, podría acceder a la sesión de la víctima. Renovar el ID al cambiar los privilegios rompe esta cadena.
Mecanismo y causa raíz
La fijación de sesión requiere que el atacante influya en el identificador que utiliza la víctima y que la aplicación no lo sustituya al autenticar. Los atributos de cookie aportan defensa en profundidad, pero ninguno sustituye la rotación: HttpOnly limita la lectura desde scripts, Secure limita el transporte a HTTPS, SameSite reduce algunos envíos entre sitios y __Host- restringe el alcance de la cookie en navegadores compatibles.
# VULNERABLE: custom session code keeps the pre-authentication ID.
def login_view(request):
user = authenticate(request, request.POST["username"],
request.POST["password"])
if user is not None:
# BUG: privilege changes, but the session ID does not.
request.session["user_id"] = user.pk
request.session["authenticated"] = True
return redirect("/account/")
return redirect("/login/")
# HARDENED: Django login() rotates the session key on authentication.
from django.contrib.auth import authenticate, login
def login_view(request):
user = authenticate(request, request.POST["username"],
request.POST["password"])
if user is not None:
# Uses Django's supported authentication/session integration.
login(request, user)
return redirect("/account/")
return redirect("/login/")
# settings.py: use HTTPS, host-only scope, and a deliberate SameSite policy.
SESSION_COOKIE_NAME = "__Host-sessionid"
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Lax"
SESSION_COOKIE_PATH = "/"
SESSION_COOKIE_DOMAIN = None
Secuencia del ataque y ejemplo conceptual
- 1Condición previa: Otra debilidad o función permite que el atacante influya en el ID que enviará el navegador de la víctima.
- 2ID conocido: El atacante puede reconocer o reutilizar el mismo ID de sesión anónimo.
- 3Autenticación: La víctima inicia sesión mientras el navegador sigue enviando el ID conocido.
- 4Sin rotación: La aplicación eleva la sesión existente en lugar de reemplazar su identificador.
- 5Impacto condicionado: El atacante solo accede a la sesión autenticada mientras el ID conocido siga válido y utilizable.
Reglas de prevención y refuerzo para ingeniería
- ✓Renueva el ID al cambiar privilegios: Emite un ID nuevo e impredecible al iniciar sesión y en otras elevaciones de privilegios; invalida el anterior según el comportamiento documentado del framework.
- ✓Usa las API de autenticación del framework: Prefiere la integración compatible de login y sesiones (en Django,
django.contrib.auth.login()) a añadir manualmente la identidad a la sesión. - ✓Rechaza IDs controlados por el atacante: No aceptes IDs de sesión en URL. Evita la inyección de cookies desde subdominios hermanos y prueba la lógica personalizada de cookies/sesión.
- ✓Configura cada atributo para su función: Usa
SecureyHttpOnly; considera el prefijo__Host-conPath=/y sinDomain. EligeSameSite=LaxoStrictsegún los flujos legítimos de login entre sitios; SameSite no sustituye los tokens CSRF cuando hacen falta. - ✓Verifica la transición: En una prueba automatizada, registra el ID anónimo, autentica, confirma que cambió y comprueba que el antiguo no accede a la sesión autenticada.