OWASP: A04 2025 - Cryptographic Failures
¿Qué es Cryptographic Failures?
Cryptographic Failures agrupa los fallos que provocan que información sensible no quede protegida correctamente mediante mecanismos criptográficos. El problema puede aparecer porque los datos se transmiten o almacenan sin cifrar, porque se utilizan algoritmos o configuraciones débiles, porque las contraseñas se almacenan de forma inadecuada o porque las claves criptográficas se gestionan incorrectamente.
En este artículo analizamos las siguientes áreas:
Datos sensibles en tránsito
Configuración TLS
Datos sensibles en reposo
Almacenamiento de contraseñas
Algoritmos y modos criptográficos débiles
Gestión de claves criptográficas
Aleatoriedad y valores predecibles
Datos sensibles en tránsito
Identifica qué información sensible intercambia la aplicación y comprueba si todos los canales por los que circula proporcionan una protección adecuada.
Presta especial atención a:
- Credenciales y formularios de autenticación.
- Cookies y tokens de sesión.
- Tokens de recuperación de contraseña o verificación de cuentas.
- Información personal o financiera.
- Claves API y otros secretos.
- Documentos o archivos sensibles.
- Comunicación entre la aplicación y servicios backend.
Una comprobación inicial consiste en determinar si la aplicación continúa siendo accesible mediante HTTP:
curl -I http://target.com
Si el servidor acepta conexiones sin cifrar, comprueba si redirige inmediatamente hacia HTTPS y si existe alguna funcionalidad que pueda utilizarse antes de que se produzca esa redirección.
Por ejemplo, una aplicación puede servir la página principal mediante HTTPS pero mantener endpoints secundarios, APIs, descargas o recursos internos accesibles mediante HTTP.
El riesgo aumenta cuando credenciales, identificadores de sesión u otra información sensible pueden transmitirse por un canal sin cifrar, ya que un atacante con capacidad de observar el tráfico podría acceder directamente a esos valores.
También debes revisar referencias generadas por la propia aplicación:
http://target.com/api/
http://api.target.com/
ws://target.com/socket
La existencia de enlaces HTTP no confirma por sí sola una vulnerabilidad. Determina si el recurso transmite información sensible o permite realizar operaciones que deberían estar protegidas.
HSTS
HSTS indica al navegador que el dominio debe utilizar HTTPS durante el periodo configurado y reduce la posibilidad de que futuras conexiones sean degradadas a HTTP.
La ausencia de HSTS no significa automáticamente que exista exposición directa de información sensible. Debes relacionarla con la posibilidad real de establecer conexiones HTTP y con el comportamiento de la aplicación.
Comprueba si las respuestas HTTPS incluyen Strict-Transport-Security:
curl -sI https://target.com | grep -i strict-transport-security
Por ejemplo:
Strict-Transport-Security: max-age=31536000; includeSubDomains
Red Team OPSEC
Para validar la exposición de datos en tránsito normalmente no es necesario capturar tráfico perteneciente a usuarios reales.
Utiliza cuentas y datos de prueba y limita la evidencia a la información mínima necesaria para demostrar que el canal permite transmitir contenido sensible sin la protección esperada.
Configuración TLS
El uso de HTTPS no garantiza por sí solo que el canal esté correctamente protegido. Comprueba qué versiones de TLS, suites criptográficas y certificados acepta el servidor.
Una comprobación manual sencilla puede realizarse mediante openssl:
openssl s_client -connect target.com:443 -servername target.com
Revisa especialmente:
- Versión de TLS negociada.
- Suite criptográfica utilizada.
- Certificado presentado por el servidor.
- Nombre o nombres para los que resulta válido.
- Fecha de inicio y expiración.
- Cadena de confianza.
Para comprobar versiones concretas puedes intentar establecer la conexión explícitamente:
openssl s_client -connect target.com:443 -servername target.com -tls1_2
openssl s_client -connect target.com:443 -servername target.com -tls1_3
También pueden utilizarse herramientas de enumeración para obtener una visión global de la configuración:
nmap --script ssl-enum-ciphers -p 443 target.com
Presta especial atención a protocolos obsoletos, suites débiles o configuraciones que permitan negociar parámetros considerablemente inferiores a los esperados.
Una configuración moderna debería priorizar TLS 1.3 y mantener TLS 1.2 únicamente cuando sea necesario por compatibilidad. La aceptación de versiones anteriores debe analizarse teniendo en cuenta el contexto y los clientes que realmente necesite soportar la aplicación.
Certificados
Un certificado debe ser válido para el nombre utilizado, encontrarse dentro de su periodo de validez y permitir construir una cadena de confianza correcta.
Los errores de validación cobran especial importancia en clientes, aplicaciones móviles, agentes o integraciones backend que ignoran errores de certificado y continúan la conexión.
En una aplicación web convencional, un certificado expirado o emitido para un nombre diferente suele ser evidente para el navegador. Sin embargo, en comunicaciones servidor a servidor una validación incorrecta puede permitir que el cliente confíe en un endpoint que no debería ser considerado legítimo.
Red Team OPSEC
La enumeración de protocolos y suites TLS puede generar múltiples conexiones en poco tiempo. Utiliza únicamente las comprobaciones necesarias para caracterizar la configuración y evita repetir escaneos completos cuando una validación dirigida sea suficiente.
Datos sensibles en reposo
Identifica dónde almacena la aplicación información sensible y determina si queda protegida de acuerdo con su nivel de sensibilidad.
Algunos lugares habituales son:
- Bases de datos.
- Archivos de configuración.
- Backups y exportaciones.
- Logs.
- Sistemas de caché.
- Almacenamiento de objetos.
- Colas de mensajes.
- Discos o volúmenes persistentes.
El análisis debe centrarse en la información que quedaría expuesta si un atacante obtuviera acceso al almacenamiento subyacente.
Por ejemplo, si durante la evaluación puedes consultar una tabla de usuarios, una exportación o una copia de seguridad, comprueba si aparecen directamente valores como:
password
credit_card_number
private_key
api_key
access_token
refresh_token
No todos estos valores requieren el mismo tratamiento. Una contraseña, por ejemplo, no debería almacenarse mediante cifrado reversible, mientras que determinados datos que la aplicación necesita recuperar posteriormente pueden requerir cifrado.
También debes comprobar si existen copias secundarias de información que originalmente sí estaba protegida. Un campo cifrado correctamente en la base de datos puede terminar expuesto en texto claro dentro de un log, una exportación CSV, un sistema de analítica o una copia de seguridad.
La vulnerabilidad se confirma cuando información que requiere protección criptográfica queda disponible en texto claro o mediante un mecanismo que no ofrece una protección adecuada.
Red Team OPSEC
No recopiles grandes volúmenes de información sensible únicamente para demostrar que se almacena sin protección.
Una muestra mínima y controlada suele ser suficiente. Siempre que sea posible utiliza datos pertenecientes a cuentas de prueba y evita acceder a secretos o información personal de terceros si no es necesario para validar el hallazgo.
Almacenamiento de contraseñas
Las contraseñas presentan un caso particular: normalmente no existe ninguna necesidad de recuperar su valor original, por lo que no deberían almacenarse mediante cifrado reversible.
Durante una evaluación con acceso autorizado a una base de datos, backup, exportación o código fuente, identifica cómo se almacenan las credenciales.
Algunos ejemplos fácilmente reconocibles son:
5f4dcc3b5aa765d61d8327deb882cf99
7c222fb2927d828af22f592134e8932480637c0d
$2b$12$...
$argon2id$v=19$m=65536,t=3,p=4$...
Los primeros valores podrían corresponder a hashes rápidos como MD5 o SHA-1, mientras que formatos como bcrypt o Argon2 suelen incluir parámetros adicionales dentro de la propia representación.
No determines la seguridad únicamente por la longitud del valor almacenado. Confirma, cuando sea posible, qué función se utiliza revisando la implementación o la configuración de la aplicación.
Una implementación adecuada debería utilizar una función específica para almacenamiento de contraseñas, con sal individual y un factor de trabajo suficientemente costoso.
Sal reutilizada o inexistente
Una señal útil consiste en comprobar si dos cuentas con la misma contraseña producen exactamente el mismo valor almacenado.
Si puedes utilizar dos cuentas de prueba, establece temporalmente la misma contraseña y compara los resultados. Valores idénticos pueden indicar que no existe una sal individual o que el esquema utilizado es determinista de una forma que facilita ataques contra múltiples hashes simultáneamente.
No es necesario intentar recuperar contraseñas reales para demostrar una implementación débil. La identificación del algoritmo, sus parámetros y el tratamiento de la sal suele proporcionar evidencia suficiente.
Red Team OPSEC
Evita realizar cracking masivo de hashes pertenecientes a usuarios reales salvo que este tipo de actividad esté expresamente incluido en el alcance.
Para caracterizar un almacenamiento débil normalmente basta con identificar el algoritmo y sus parámetros o demostrar el comportamiento utilizando.
Algoritmos y modos criptográficos débiles
Cuando puedas revisar código, configuración, aplicaciones cliente o formatos de datos, busca primitivas criptográficas obsoletas o utilizadas de forma incorrecta.
Algunos indicadores habituales son referencias a:
MD5
SHA1
DES
3DES
RC4
AES/ECB
RSA/ECB/PKCS1Padding
La aparición de uno de estos términos no confirma automáticamente una vulnerabilidad. Debes determinar para qué se utiliza y qué propiedad de seguridad intenta proporcionar.
Por ejemplo, utilizar SHA-1 únicamente como identificador no criptográfico de un fichero no tiene el mismo impacto que utilizarlo para almacenar contraseñas o verificar una firma de seguridad.
Cifrado sin autenticación
El cifrado proporciona confidencialidad, pero determinadas implementaciones no garantizan por sí mismas que el contenido no haya sido modificado.
Durante la revisión, determina si la aplicación utiliza mecanismos de cifrado autenticado cuando necesita proteger simultáneamente confidencialidad e integridad.
Presta atención a implementaciones que utilicen primitivas de bajo nivel y construyan manualmente combinaciones de cifrado, padding y autenticación. Estos diseños son más propensos a errores que el uso de construcciones criptográficas estándar proporcionadas por bibliotecas consolidadas.
IV y nonce
Algunos modos de cifrado requieren un vector de inicialización o un nonce con propiedades concretas. Reutilizar estos valores bajo una misma clave puede degradar o destruir las garantías de seguridad del esquema.
Si el formato cifrado incluye estos campos, compara varias operaciones realizadas sobre datos de prueba y comprueba si el valor se reutiliza de forma sistemática.
La repetición no siempre implica una vulnerabilidad por sí sola: su impacto depende del algoritmo y del modo de operación utilizado. La validación debe relacionar el comportamiento observado con los requisitos concretos de la primitiva criptográfica.
Red Team OPSEC
Prioriza el análisis de código, configuración y datos generados por cuentas de prueba antes que la manipulación de información cifrada perteneciente a usuarios reales.
Evita modificar blobs, cookies o estructuras criptográficas utilizadas por sesiones reales cuando un conjunto de pruebas controlado sea suficiente para validar la debilidad.
Gestión de claves criptográficas
Un algoritmo robusto deja de proporcionar protección si la clave utilizada puede obtenerse fácilmente o se gestiona de forma insegura.
Durante la evaluación, busca claves y secretos en ubicaciones como:
.env
application.properties
appsettings.json
config.yml
Dockerfile
docker-compose.yml
values.yaml
*.pem
*.key
También revisa código fuente, repositorios, historial de cambios, pipelines de CI/CD y artefactos de despliegue cuando formen parte del alcance.
Algunos patrones típicos son:
ENCRYPTION_KEY=
SECRET_KEY=
PRIVATE_KEY=
MASTER_KEY=
JWT_SECRET=
La presencia de una clave dentro de un archivo no implica necesariamente una exposición. Debes determinar quién puede acceder a ese recurso y si la ubicación forma parte del mecanismo previsto de gestión de secretos.
Presta especial atención a:
- Claves incluidas directamente en el código fuente.
- Claves almacenadas junto a los datos que protegen sin separación efectiva.
- Una misma clave reutilizada entre entornos o aplicaciones diferentes.
- Claves por defecto compartidas entre instalaciones.
- Ausencia de mecanismos de rotación cuando el diseño los requiere.
- Claves antiguas que continúan siendo válidas indefinidamente.
- Permisos excesivos sobre almacenes de secretos.
Claves hardcoded en aplicaciones cliente
Las claves incluidas dentro de JavaScript, aplicaciones móviles o software distribuido al usuario deben considerarse recuperables por quien tenga acceso al cliente.
Por ejemplo:
const encryptionKey = "e7b9c41f0d2a...";
El hecho de ofuscar o dividir el valor no convierte el secreto en inaccesible si el propio cliente necesita reconstruirlo para utilizarlo.
El impacto depende de qué permita hacer esa clave. Una clave utilizada únicamente para proteger datos locales sin un límite de confianza externo no tiene el mismo impacto que una clave compartida que permita descifrar información de todos los usuarios o autenticarse frente a un servicio backend.
Red Team OPSEC
Si encuentras una clave o secreto real, evita utilizarlo contra sistemas adicionales únicamente para comprobar hasta dónde funciona.
Primero identifica su propósito mediante el contexto disponible y limita cualquier validación activa a los sistemas incluidos explícitamente en el alcance.
No descargues almacenes completos de secretos cuando un único valor de prueba sea suficiente para demostrar el problema de gestión de claves.
Aleatoriedad y valores predecibles
La criptografía también depende de que determinados valores sean impredecibles. Tokens de recuperación, identificadores de sesión, claves, nonces y otros secretos generados por la aplicación deben utilizar una fuente de aleatoriedad adecuada cuando su seguridad dependa de que un atacante no pueda adivinarlos.
Busca implementaciones que generen valores sensibles mediante funciones destinadas a simulación o uso general, por ejemplo:
Math.random()
random.random()
random.randint(...)
java.util.Random
Estas funciones pueden ser perfectamente válidas para otros propósitos, pero no deberían utilizarse cuando la seguridad depende de la impredecibilidad del resultado.
Durante una evaluación black-box, recopila únicamente valores generados para cuentas o acciones de prueba y analiza si presentan patrones evidentes, secuencias, timestamps, contadores o una entropía claramente insuficiente.
Por ejemplo, un token como:
reset-1723456789-1042
Revela directamente componentes predecibles y debería analizarse para determinar qué parte del valor actúa realmente como secreto.
No consideres vulnerable un token simplemente porque tenga una estructura reconocible. Muchos formatos incluyen información pública junto a una firma o componente aleatorio suficientemente robusto.
La vulnerabilidad aparece cuando un atacante puede reducir de forma práctica el espacio de búsqueda, predecir valores futuros o generar un valor que la aplicación acepte como secreto válido.
Red Team OPSEC
Evita solicitar grandes cantidades de tokens o sesiones únicamente para realizar análisis estadístico si una muestra reducida permite identificar el patrón.
No intentes utilizar valores predichos sobre cuentas de terceros cuando puedas demostrar el comportamiento mediante varias cuentas o flujos de prueba bajo tu control.