highCWE-338A02:2021

PRNG Debil para Seguridad

Usar Math.random() o Date.now() para generar tokens, IDs de sesion o codigos de reset produce valores predecibles que los atacantes pueden adivinar o reproducir.

Cómo Funciona

Math.random() usa un generador de numeros pseudo-aleatorios (PRNG) disenado para velocidad, no seguridad. Su salida es determinista dado el estado de la semilla, y el estado puede ser reconstruido a partir de salidas observadas. Un atacante que vea algunos valores generados puede predecir todos los valores futuros. Date.now() es aun peor — retorna el timestamp actual en milisegundos, que es trivialmente adivinable. Cuando estos se usan para generar tokens de reset de password, API keys, IDs de sesion o codigos de verificacion, un atacante puede predecir o hacer fuerza bruta a los valores generados. Un timestamp de 13 digitos tiene solo alrededor de 100,000 valores posibles si el atacante conoce el tiempo aproximado. Un valor de Math.random() tiene como maximo 2^52 bits de entropia pero es reducible al estado interno con solo unas pocas observaciones.

Código Vulnerable
// Weak token generation
function generateResetToken() {
  return Math.random().toString(36).substring(2);
}
function generateApiKey() {
  return 'key_' + Date.now().toString(36);
}
function generateSessionId() {
  return Math.random().toString(16).slice(2) +
    Math.random().toString(16).slice(2);
}
Código Seguro
const crypto = require('crypto');
function generateResetToken() {
  return crypto.randomBytes(32).toString('hex');
}
function generateApiKey() {
  return 'key_' + crypto.randomBytes(24).toString('base64url');
}
function generateSessionId() {
  return crypto.randomUUID();
}

Ejemplo Real

En 2020, investigadores encontraron que un CMS popular generaba tokens de reset de password usando Math.random(). Al observar algunos tokens, reconstruyeron el estado del PRNG y predijeron tokens futuros. Esto les permitio generar links validos de reset de password para cualquier cuenta, incluyendo admin, sin acceso al correo del usuario.

Cómo Prevenirlo

  • Siempre usa crypto.randomBytes() o crypto.randomUUID() para valores sensibles de seguridad
  • Nunca uses Math.random() o Date.now() para tokens, llaves o identificadores
  • Genera al menos 32 bytes (256 bits) de entropia para tokens de seguridad
  • Usa librerias establecidas como uuid v4 que internamente usan aleatoriedad cripto-segura

Tecnologías Afectadas

Node.jsPythonJavaGoC#

Data Hogo detecta esta vulnerabilidad automáticamente.

Escanea Tu Repo Gratis

Vulnerabilidades Relacionadas