OAuth Sin Parámetro State
Flujo de autorización OAuth implementado sin un parámetro `state` aleatorio, permitiendo ataques CSRF que vinculan la cuenta de una víctima con la identidad OAuth del atacante.
Cómo Funciona
El parámetro `state` de OAuth es un valor aleatorio que generas, incluyes en la URL de autorización y verificas cuando regresa el callback. Sin él, un atacante puede iniciar un flujo OAuth, obtener la URL del callback (antes de completar el login) y enviársela a una víctima. La víctima hace clic, completa OAuth y su cuenta queda vinculada a la identidad social del atacante.
// MAL: redirección OAuth sin state
export async function GET() {
const authUrl = `https://github.com/login/oauth/authorize?client_id=${CLIENT_ID}&scope=user`;
return Response.redirect(authUrl);
}// BIEN: genera y verifica el parámetro state
export async function GET(req: Request) {
const state = crypto.randomUUID();
// Guarda el state en la sesión para verificarlo después
const session = await getSession();
session.oauthState = state;
await session.save();
const authUrl = `https://github.com/login/oauth/authorize?client_id=${CLIENT_ID}&state=${state}&scope=user`;
return Response.redirect(authUrl);
}Ejemplo Real
Las implementaciones de OAuth de Facebook, Twitter y GitHub en apps de terceros han tenido vulnerabilidades por falta del parámetro state reportadas. La explotación exitosa significa que un atacante puede vincular su cuenta de GitHub a la cuenta de la víctima en tu app, obteniendo acceso.
Cómo Prevenirlo
- Siempre genera un parámetro state criptográficamente aleatorio (usa crypto.randomUUID() o nanoid)
- Guarda el state en la sesión del usuario antes de redirigir al proveedor OAuth
- En el callback, verifica que el state devuelto coincida exactamente con el guardado
- Usa una librería OAuth (next-auth, passport.js) que maneje la gestión del state por ti
Tecnologías Afectadas
Data Hogo detecta esta vulnerabilidad automáticamente.
Escanea Tu Repo GratisVulnerabilidades Relacionadas
Fijación de Sesión
highEl servidor reutiliza el mismo ID de sesión antes y después del login, permitiendo a un atacante que plantó un ID de sesión conocido secuestrar la sesión autenticada.
Sin Bloqueo de Cuenta / Protección contra Fuerza Bruta
mediumEndpoints de login sin rate limiting ni mecanismo de bloqueo, permitiendo a atacantes probar combinaciones ilimitadas de usuario y contraseña hasta encontrar credenciales válidas.
Política de Contraseña Débil
mediumSin requisitos de longitud mínima, complejidad o verificación contra contraseñas comunes en el registro o cambio de contraseña, haciendo las cuentas fácilmente vulnerables a fuerza bruta.
Token No Invalidado al Hacer Logout
mediumTokens JWT o de sesión que siguen siendo válidos después de que un usuario hace logout porque no hay mecanismo de revocación server-side, permitiendo que tokens robados se usen indefinidamente.