Introducción
En el panorama actual de la seguridad de aplicaciones móviles y servicios basados en API, la protección de los flujos de usuario es un punto crítico de falla. Las aplicaciones modernas, al depender de interfaces de programación de aplicaciones (APIs) para la gestión de datos y la lógica de negocio, exponen una superficie de ataque considerable. Este análisis se centra en examinar la implementación de la funcionalidad de registro, autenticación y recuperación de credenciales de la aplicación móvil Android de una pulsera de salud mediante la interceptación de tráfico de red utilizando herramientas como Frida y un proxy web.
Análisis
1. Enumeración de usuarios y flujos de registro débiles
El análisis comienza con la apertura de la aplicación e interceptación de las comunicaciones en red. Se observa un flujo de negocio que permite al usuario optar por la creación de una cuenta o la utilización de la aplicación sin registro.
Una vulnerabilidad crítica se detecta en la ruta utilizada para verificar la existencia de una cuenta. Mediante la solicitud HTTP, es posible determinar si una dirección de correo electrónico ya está registrada en el sistema, permitiendo la enumeración completa de usuarios existentes en la base de datos.
:method: POST
:path: /api/users/CheckUserName?username=<EMAIL_ADDRESS>
:authority: backend.application.tld
:scheme: https
user-agent: okhttp/4.12.0
El proceso de registro se limita a solicitar únicamente un correo electrónico y una contraseña. La aplicación presenta una interfaz que permite contraseñas de 6 a 20 caracteres sin imponer requisitos de complejidad. Sin embargo, el análisis de servidor revela una laxitud aún mayor: el servidor acepta contraseñas de un solo carácter.
:method: POST
:path: /api/users/register
:authority: backend.application.tld
:scheme: https
content-type: application/json; charset=UTF-8
user-agent: okhttp/4.12.0
{"username":"<EMAIL_ADDRESS>","password":"<PASSWORD>"}
2. Ausencia de verificación de posesión y autenticación débil
Tras el registro, la aplicación permite continuar el proceso sin confirmar la posesión de la cuenta a través de un enlace o un código de un solo uso. Esto permite que cualquier correo electrónico no registrado sea utilizado para crear una cuenta.
La posterior sesión se establece mediante la ruta de verificación, la cual envía datos como modelo de dispositivo, versión del sistema operativo y tipo de aplicación. Aunque se intenta enviar el código IMEI, en versiones recientes de Android se detecta que la aplicación no posee los permisos necesarios para acceder a este identificador.
:method: POST
:path: /api/users/verify
:authority: backend.application.tld
:scheme: https
content-type: application/json; charset=UTF-8
user-agent: okhttp/4.12.0
{"phoneband":"<PHONE_MODEL>","ImeiCode":"no permission","username":"<EMAIL_ADDRESS>","SysType":"android-sport","password":"<PASSWORD>","SysVersion":"16"}
Se constata que esta ruta carece de cualquier mecanismo de protección contra ataques de fuerza bruta. Es posible realizar un mínimo de 100 intentos de sesión sin que se aplique ningún bloqueo o restricción de tasa, lo que incrementa significativamente la probabilidad de un ataque automatizado de fuerza bruta.
{
"UserId": "<USER_ID>",
"ExpiresIn": "2026...",
"AccessToken": "<SESSION_ACCESS_TOKEN>",
"RefreshToken": "<SESSION_REFRESH_TOKEN>",
"CreatedDate": "2026..."
}
Los tokens de acceso y refresco tienen una duración de un mes desde la fecha de creación. Las peticiones subsiguientes se autentican mediante la cabecera HTTP Authorization: token <SESSION_ACCESS_TOKEN>.
3. Exposición de datos sensibles
Al realizar una petición a la ruta /api/users/profile para obtener los datos de la cuenta recién creada, se evidencia una falla crítica de seguridad: la contraseña se devuelve sin cifrar. Esto confirma que el dato se está almacenando en la base de datos sin la aplicación de un mecanismo de cifrado robusto, exponiendo la credencial en caso de una brecha de la base de datos.
{
"UserId": "<USER_ID>",
"Nickname": "<EMAIL_ADDRESS>",
"Email": "<EMAIL_ADDRESS>",
"HXUserName": "<USER_ID>",
"HXUserPassword": "<PASSWORD>",
}
4. Vulnerabilidades en el flujo de recuperación de contraseña
El análisis procede a verificar el mecanismo de recuperación de contraseña olvidada. El primer paso implica ingresar el correo electrónico, lo cual nuevamente activa la ruta de enumeración. Si la cuenta existe, se dispara una petición para enviar el código de verificación.
:method: POST
:path: /api/send/SendMailCode
:authority: backend.application.tld
:scheme: https
content-type: application/json; charset=UTF-8
user-agent: okhttp/4.12.0
{"vericode":"<VERIFICATION_CODE>","subject":"Application","language":"es","type":"android-sport","useremail":"<EMAIL_ADDRESS>","displayName":"Application Verification Code"}
Se observa varias irregularidades en este proceso. Primeramente, el código de un solo uso para la verificación se genera localmente en el dispositivo mediante una cadena numérica de cuatro cifras, y no en el servidor. Más preocupante es que esta ruta se utiliza para disparar el envío de correos electrónicos sin importar si el correo está registrado. Los campos vericode, subject y displayName son personalizables. Este es un ejemplo de correo recibido.
From: "Application Verification Code" <system@application.tld>
To: <EMAIL_ADDRESS>
Subject: Application
Dear Application Verification Code users :
Greetings!
Your verification code is: <VERIFICATION_CODE>
For the security of your account, please enter the verification code within 1 hour
If not operated by yourself, please ignore this email
send by system automatically, please do not reply
Se ha comprobado que si el cliente de correo electrónico recibe el mensaje en formato HTML en lugar de texto plano, es posible inyectar código HTML o JavaScript en el campo displayName (ejemplo: displayName": "<script>alert('Verification Code')</script>"). El uso de secuencias como <!-- permite ocultar el contenido restante del correo. Los clientes de correo sin filtrado son vulnerables a ataques de Cross-Site Scripting (XSS) a través de correo. Adicionalmente, la manipulación de los parámetros subject y del cuerpo del correo permite utilizar esta ruta para enviar correos maliciosos a cualquier dirección de correo electrónico, facilitando campañas de phishing.
Finalmente, el proceso de recuperación culmina con la petición para cambiar la contraseña.
:method: POST
:path: /api/users/findpassword
:authority: backend.application.tld
:scheme: https
content-type: application/json; charset=UTF-8
user-agent: okhttp/4.12.0
{"username":"<EMAIL_ADDRESS>","NewPassword":"<PASSWORD>"}
Se observa que esta ruta permite modificar la contraseña de un usuario sin requerir la presentación de ningún código de verificación previamente enviado. Esto representa una vulnerabilidad de Secuestro de Cuenta de nivel crítico, permitiendo a un atacante cambiar la contraseña de cualquier usuario simplemente conociendo su correo electrónico. Tras este cambio, el usuario original no recibe notificación alguna, quedando su cuenta comprometida sin su conocimiento.
Conclusión
El análisis de la aplicación revela un conjunto de vulnerabilidades de seguridad de riesgo crítico y alto impacto. La arquitectura actual presenta múltiples puntos de fallo que, cuando se combinan, permiten a un atacante realizar un secuestro de cuenta completo y sin resistencia, con la capacidad de operar a escala automatizada.