lowCWE-204A07:2021

Enumeración de Usuarios por Mensajes de Error Distintos

Endpoints de login o reset de contraseña que devuelven mensajes de error diferentes para 'email no encontrado' vs 'contraseña incorrecta', permitiendo a atacantes confirmar qué direcciones de email están registradas.

Cómo Funciona

Si tu login dice 'No se encontró cuenta con este email' para usuarios desconocidos e 'Contraseña incorrecta' para usuarios conocidos, los atacantes pueden recorrer listas de emails para descubrir cuáles están registrados. Esto impulsa phishing dirigido, credential stuffing y saber a quién perseguir. Un único mensaje cubre ambos casos.

Código Vulnerable
// MAL: mensajes diferentes revelan existencia de cuenta
if (!user) return Response.json({ error: 'No hay cuenta con este email' }, { status: 401 });
if (!await bcrypt.compare(password, user.passwordHash)) {
  return Response.json({ error: 'Contraseña incorrecta' }, { status: 401 });
}
Código Seguro
// BIEN: mismo mensaje independientemente de cuál check falló
if (!user || !await bcrypt.compare(password, user.passwordHash)) {
  return Response.json({ error: 'Email o contraseña inválidos' }, { status: 401 });
}

Ejemplo Real

Los flujos de reset de contraseña son especialmente propensos a esto: 'Te enviamos un email de reset' vs 'No hay cuenta con ese email' le dice exactamente a los atacantes quién está registrado. Muchas plataformas importantes recibieron reportes de bounty por esto, incluyendo LinkedIn y Twitter.

Cómo Prevenirlo

  • Usa el mismo mensaje de error para los casos 'usuario no encontrado' y 'contraseña incorrecta'
  • Para reset de contraseña, siempre di 'Si ese email está registrado, recibirás un link' — independientemente
  • Aplica el mismo retardo de respuesta independientemente de si el usuario existe (previene ataques de timing)
  • Limita la tasa de intentos de enumeración por IP

Tecnologías Afectadas

nodejsNext.jsPythonPHP

Data Hogo detecta esta vulnerabilidad automáticamente.

Escanea Tu Repo Gratis

Vulnerabilidades Relacionadas