| ID | Hallazgo | Plataforma | CVSS | Severidad | OWASP MSTG |
|---|---|---|---|---|---|
| FM-001 | Clave Stripe hardcoded en APK (sk_live_…) | Android | 9.8 | Crítico | MSTG-STORAGE-14 |
| FM-002 | Firebase DB sin autenticación — lectura/escritura libre | AndroidiOS | 9.1 | Crítico | MSTG-NETWORK-6 |
| FM-003 | Bypass de BiometricPrompt sin clave criptográfica vinculada | Android | 8.8 | Crítico | MSTG-AUTH-8 |
| FM-004 | SSL Pinning bypasseable con Frida — MITM total | AndroidiOS | 7.4 | Alto | MSTG-NETWORK-3 |
| FM-005 | ContentProvider exportado — lectura de transacciones sin permisos | Android | 7.2 | Alto | MSTG-PLATFORM-2 |
| FM-006 | Deep link payment sin validación de origen — IDOR | iOS | 7.1 | Alto | MSTG-PLATFORM-3 |
| FM-007 | JWT almacenado en SharedPreferences — accesible sin root en backup | Android | 6.8 | Alto | MSTG-STORAGE-1 |
| FM-008 | Keychain iOS — token con kSecAttrAccessibleAlways | iOS | 5.5 | Medio | MSTG-STORAGE-2 |
| FM-009 | Endpoint /api/v1/ sin rate-limiting activo — brute force | Backend | 5.3 | Medio | MSTG-NETWORK-1 |
| FM-010 | Google Maps API Key sin restricción de dominio | AndroidiOS | 5.0 | Medio | MSTG-RESILIENCE-2 |
Durante el análisis estático del APK decompilado con jadx se localizó la clave secreta de Stripe en texto claro dentro del archivo de configuración de red. Esta clave permite realizar cargos, reembolsos y listar clientes de toda la base.
La URL de Firebase se extrajo del APK. Las reglas de seguridad permiten lectura y escritura anónima sobre toda la base de datos, exponiendo el historial de transacciones de todos los usuarios.
allow read, write: if request.auth != null; como mínimo inmediato. Implementar reglas granulares por UID. Habilitar App Check para validar que las peticiones vienen de la app legítima.
La app usa BiometricPrompt para aprobar transferencias de más de 500€. El resultado de la biometría se verifica únicamente en el callback de la UI sin vincular ninguna operación criptográfica al resultado de autenticación. Cualquier proceso con Frida puede interceptar el callback y forzar éxito.
setUserAuthenticationRequired(true)). El servidor debe validar el JWT firmado con esa clave, que solo existe si la biometría fue genuina.
El SSL pinning implementado con OkHttp CertificatePinner es vulnerable al bypass universal de Frida. Se verificó intercepción completa del tráfico hacia api.finmobile.es incluyendo tokens JWT, datos de tarjeta y confirmaciones de pago.
El ContentProvider com.finmobile.pay.provider está declarado con android:exported="true" sin requerir ningún permiso. Cualquier app instalada en el mismo dispositivo puede consultar el historial completo de transacciones.
android:protectionLevel="signature") y requerirlo en el provider.
| Prioridad | Acción | ID | Esfuerzo | Plazo |
|---|---|---|---|---|
| Inmediata | Rotar clave Stripe + mover pago al backend | FM-001 | 2h | HOY |
| Inmediata | Bloquear Firebase DB con reglas de autenticación | FM-002 | 1h | HOY |
| Esta semana | Migrar BiometricPrompt a CryptoObject | FM-003 | 3 días dev | 14 días |
| Este sprint | Añadir detección Frida + Play Integrity | FM-004 | 5 días dev | 30 días |
| Este sprint | ContentProvider: exported=false o permiso firma | FM-005 | 2h | 14 días |
| Este sprint | Validar origen de deep links con Universal Links | FM-006 | 1 día dev | 14 días |
| Próximo sprint | Mover JWT a EncryptedSharedPreferences | FM-007 | 4h | 30 días |