Vulnerabilidad de Truncamiento en Bcrypt: Análisis y Mitigaciones
Por StringManolo - Cybersecurity Researcher
Publicado: 4 de Noviembre 2025 | Tiempo de lectura: 5 min
⚠️ ADVERTENCIA: Sistemas que usan bcrypt sin validar longitud de contraseña pueden ser vulnerables a bypass de autenticación.
Introducción
Bcrypt es ampliamente usado para el almacenamiento seguro de contraseñas, pero su limitación de 72 bytes puede ser explotada si no se valida correctamente la longitud de entrada.
Problema Técnico
Truncamiento Silencioso
Bcrypt procesa solo los primeros 72 bytes de la contraseña, ignorando silenciosamente cualquier contenido adicional.
Código
// Ejemplo de comportamiento bcrypt.hash("a".repeat(72)) == bcrypt.hash("a".repeat(72) + "cualquier_cosa")
Bytes vs Caracteres
La confusión surge al diferenciar bytes de caracteres:
- Carácter ASCII: 1 byte
- Carácter Unicode: 2-4 bytes
- Máximo seguro (estimado): 18 caracteres (18 × 4 = 72 bytes)
Impacto en Seguridad
Vectores de Ataque
- Bypass de autenticación con prefijos comunes
- Colisiones de hash
- Reducción de entropía efectiva
Demostración Práctica
CTF educativo disponible: 🔗 Demo Interactivo
Código
testAdminPassword("a".repeat(72)); // → Valida testAdminPassword("a".repeat(72) + "ADMIN"); // → Valiida
Ejemplo de interpretación de bytes
Ingresa en el CTF en una nueva pestaña y registra un nuevo usuario llamado Manolo.
Utiliza como contraseña para el usuario MANOLO 36 letras 'ñ' seguidas de cualquier texto, puedes copiar y pegar: ññññññññññññññññññññññññññññññññññññMANOLO123
Registra otro usuario llamado PACO
Utiliza como contraseña para el usuario PACO 36 letras 'ñ' seguidas de cualquier texto, puedes copiar y pegar: ññññññññññññññññññññññññññññññññññññPACO456
Las contraseñas son distintas, pero puedes ingresar en la cuenta de cualquiera de los 2 usuarios usando la contraseña ññññññññññññññññññññññññññññññññññññABCDEFG
Esto sucede porque el carácter 'ñ' ocupa 2 bytes, ya que es un carácter especial (Unicode). Y Bcrypt trunca tras los 72 primeros bytes (36 ñ de 2 bytes == 72 bytes).
Emojis y otros caracteres especiales (como letras en otros idiomas) pueden utilizar hasta un máximo de 4 bytes por caracter.
Mitigaciones
- Validación de Entrada
- Limitar a 18 caracteres máximo
- Utilizar otro algoritmo de hashing
- Limitar a 18 caracteres máximo
- Implementación Segura
Código
const validatePassword = (pwd) => { if (pwd.length > 18) { throw new Error("Maximo 18 caracteres"); } return true; }
- Alternativas
- Argon2id (recomendado)
- PBKDF2
- Scrypt
- Argon2id (recomendado)
Conclusión
Bcrypt sigue siendo seguro cuando se implementa correctamente. La clave está en validar la longitud de contraseñas (18 caracteres máximo) o migrar a algoritmos modernos como Argon2id.
Vulnerabilidades Relacionadas
- CVE-2025-22228 - BCryptPasswordEncoder.matches() Vulnerability
- Bcrypt hashing library bug leaves Node.js applications open to brute-force attacks
- Okta Bcrypt Vulnerability Exposes Critical API Design Flaws
- Properly handle that PHP bcrypt passwords are truncated to 72 bytes





Autor





En línea

