Lista de verificación de seguridad para aplicaciones Android
Fase 0: Gobernanza, entorno y CI/CD
Aplicar puertas de validación en CI (CI gates)
- Ejecutar comprobaciones estáticas en cada PR: ktlint / Android Lint, pruebas unitarias/UI, auditoría de dependencias (Gradle, SBOM).
- Bloquear el lanzamiento ante hallazgos SAST/SCA/DAST Altos/Críticos; cero errores de lint en ramas de lanzamiento.
Manejo de secretos
- Sin secretos en el código fuente, BuildConfig, AndroidManifest.xml, recursos o registros.
- Utilizar un gestor de entorno/secretos (ej. Gradle secrets, cloud KMS); ocultar secretos en las analíticas.
- Rotar claves/tokens periódicamente y ante sospecha de filtración.
Evidencia y trazabilidad
- Archivar informes de escaneo, SBOM, registros de compilación y notas de la versión con cada artefacto.
Automatización de escaneos
- Integrar una plataforma móvil de SAST/DAST/SCA en CI/CD para ejecutarla en cada PR y pre-lanzamiento y hacer fallar automáticamente las puertas de validación en caso de problemas Altos/Críticos.
Fase 1: Modelado de amenazas (Threat modeling), clasificación de datos e inventario
- Clasificar los datos (PII, credenciales, tokens, pagos) y mapear su recopilación, procesamiento, almacenamiento (SharedPreferences, archivos, bases de datos, Keystore) y transmisión.
- Identificar los límites de confianza (dispositivo, sandbox de la aplicación, Keystore, IPC/Binder, WebView, bibliotecas nativas, APIs del backend).
- Inventariar los SDKs de terceros; preferir SDKs bien mantenidos, firmados, con el mínimo privilegio; minimizar la cantidad.
Fase 2: Fortalecimiento de la compilación y configuración (Gradle + Manifest)
Ajustes de Gradle/Lanzamiento (Release settings)
- Utilizar compilaciones de lanzamiento con reducción/ofuscación de código (
minifyEnabled true,shrinkResources true). - Eliminar los símbolos de depuración del APK/AAB enviado.
- Mantener los archivos de mapeo en el servidor.
- Excluir bibliotecas de prueba/depuración del lanzamiento.
- Eliminar endpoints de desarrollo e indicadores de características (feature flags) de las compilaciones de producción.
Firmas y permisos
- Proteger las claves de firma (keystores respaldados por hardware, acceso restringido).
- Utilizar configuraciones de firma dedicadas a los lanzamientos.
- Declarar solo los permisos necesarios en
AndroidManifest.xml. - Evitar permisos peligrosos excesivos.
Configuración de la seguridad de la red
- Utilizar
networkSecurityConfigpara forzar TLS. - No permitir tráfico en texto claro (
android:usesCleartextTraffic="false"). - Utilizar anulaciones de configuración de dominio solo cuando sea necesario y por un tiempo limitado.
Higiene del Manifest
- No establecer componentes en
exported="true"a menos que sea estrictamente necesario; restringir con permisos cuando se exporten. - Eliminar los indicadores de depuración (
android:debuggable="false"en producción, noallowBackup="true"a menos que se necesite con cifrado adecuado). - Proporcionar un texto explicativo preciso (en la aplicación) para todos los permisos en tiempo de ejecución (runtime permissions).
Fase 3: Almacenamiento local y seguridad del Keystore
Uso del Keystore
- Almacenar las claves de larga duración en el Keystore de Android con la protección más sólida posible (respaldado por hardware cuando esté disponible, autenticación de usuario si la UX lo permite).
- Utilizar
setUserAuthenticationRequired(true)para claves altamente sensibles; controlar las operaciones con biometría/pantalla de bloqueo donde sea apropiado. - Eliminar los secretos envueltos por el Keystore al cerrar la sesión o cambiar de dispositivo.
- Considerar la vinculación al dispositivo (device-binding) para tokens de alto riesgo.
Archivos, SharedPreferences y bases de datos
- Evitar almacenar secretos o PII sensible en archivos de texto claro o en
SharedPreferences. - Cifrar bases de datos/archivos sensibles (ej. SQLCipher o cifrado de archivos equivalente).
- Utilizar almacenamiento privado de la aplicación (
MODE_PRIVATE). - Aplicar indicadores de protección de archivos donde sean compatibles.
- Asegurar que las copias de seguridad no contengan secretos sin cifrar.
Cachés y datos derivados
- Evitar persistir PII en cachés/archivos temporales.
- Purgar cachés/archivos temporales al cerrar sesión y como parte del paso a segundo plano, si corresponde.
- No escribir secretos en registros ni en
SharedPreferences, ni siquiera de forma temporal.
Fase 4: Salvaguardas de privacidad (UI, portapapeles, capturas de pantalla)
- Ocultar la UI sensible en las capturas de pantalla del selector de aplicaciones (ej. utilizar
FLAG_SECUREen Activities/Views sensibles). - Para flujos altamente sensibles, considerar el enmascaramiento adicional o Activities separadas en "modo seguro".
- Evitar leer el portapapeles al iniciar la aplicación; nunca colocar contraseñas/tokens de larga duración en el portapapeles.
Fase 5: Seguridad de la red y TLS/fijación (pinning)
Cumplimiento de HTTPS/TLS
- Forzar HTTPS a hosts confiables; rechazar certificados/nombres de host no válidos; desactivar los respaldos (fallbacks) a HTTP.
- Configurar tiempos de espera estrictos, backoff exponencial con variaciones (jitter) y fallar por defecto (fail closed) en errores TLS.
Fijación de certificados (Certificate pinning)
- Preferir fijaciones SPKI SHA-256; incluir al menos una fijación de respaldo por host.
- Implementar la fijación mediante OkHttp /
TrustManagerpersonalizado onetworkSecurityConfig. - Validar contra escenarios de MITM y certificados de hoja expirados/rotados.
- Planificar la rotación segura de fijaciones; incluir telemetría en caso de fallos de fijación.
Cookies y tokens
- Para flujos web, utilizar cookies seguras, HttpOnly, SameSite.
- Evitar tokens de portador (bearer tokens) de larga duración en el dispositivo.
- Borrar cookies y datos de WebView después de sesiones sensibles.
Fase 6: Autenticación, autorización y sesión
Flujos de autenticación
- Utilizar OAuth2/OIDC con PKCE para clientes públicos; nunca incrustar secretos del cliente en la aplicación.
- Preferir la autenticación basada en el sistema/navegador (Chrome Custom Tabs / navegador predeterminado) sobre WebView en la aplicación para el inicio de sesión.
Tokens
- Utilizar tokens de acceso (access tokens) de corta duración.
- Almacenar los tokens de actualización (refresh tokens) únicamente en almacenamiento cifrado vinculado a claves del Keystore.
- Rotar e invalidar tokens al cerrar sesión, cambiar de dispositivo o ante actividades sospechosas.
- Vincular sesiones al riesgo del dispositivo (device risk) cuando sea apropiado.
Autorización
- Forzar la autorización del lado del servidor; tratar las verificaciones del cliente solo como consultivas.
- Probar y prevenir las vulnerabilidades IDOR/BOLA y la escalada de privilegios en todas las APIs del backend utilizadas por la aplicación.
Fase 7: Fortalecimiento del WebView
- Utilizar WebView solo cuando sea requerido; preferir el navegador para la autenticación y pagos cuando sea posible.
Valores predeterminados
- Desactivar JavaScript a menos que sea estrictamente necesario.
- Si JavaScript está activado, restringir las capacidades y desactivar
setAllowFileAccessFromFileURLsysetAllowUniversalAccessFromFileURLs. - No habilitar
addJavascriptInterfacecon objetos que exponen métodos sensibles, especialmente en la API < 17. - Forzar listas de permitidos de navegación (hosts/rutas); bloquear
file://,javascript:y esquemas no confiables. - Utilizar un almacenamiento de WebView no persistente para sesiones sensibles cuando sea posible.
- Borrar cookies, caché e historial al cerrar sesión.
Seguridad del contenido
- Servir contenido web propio solo a través de HTTPS.
- No permitir contenido mixto (
MIXED_CONTENT_NEVER_ALLOW). - Asegurarse de que el contenido remoto sea comprobado en integridad y controlado (sin scripts de terceros no confiables a menos que sea estrictamente necesario).
Fase 8: Comunicación entre aplicaciones y enlaces profundos (deep links)
- Preferir App Links (enlaces verificados) para enlaces profundos; validar los orígenes y parámetros de los enlaces entrantes.
Esquemas e intenciones (intents) personalizados
- Si se utilizan esquemas personalizados o intenciones implícitas, asegurar la unicidad y validación robusta de todos los datos entrantes.
- Proteger las Activities/Services/BroadcastReceivers exportados con permisos o intenciones explícitas; evitar filtros de intención excesivamente amplios.
- Defenderse de la falsificación de intenciones (intent spoofing), el secuestro de URL y los redireccionamientos abiertos mediante la verificación de la identidad del llamante y los parámetros.
Fase 9: Ingeniería inversa y resistencia a la manipulación (tampering)
Reducir filtraciones estáticas
- Eliminar las compilaciones de depuración, los registros detallados, los menús de depuración y los endpoints de prueba de las compilaciones de producción.
- Ofuscar y reducir el código (ProGuard/R8) y los recursos.
- Evitar dejar cadenas significativas (claves de API, secretos) en los recursos o bibliotecas nativas.
Controles de entorno
- Detectar indicadores de root/hooking/depuradores (rutas root comunes, directorios del sistema en los que se puede escribir, frameworks de instrumentación) y registrar señales.
- Responder de forma proporcional (reducción de funcionalidad, verificación adicional o bloqueo) en función del riesgo, manteniendo la UX.
Pruebas de manipulación (Tamper testing)
- Asegurarse de que las aplicaciones reempaquetadas o re-firmadas fallen en los controles de integridad o en la certificación del servidor (ej. APIs de seguridad/certificación).
- Tratar las señales del lado del cliente como indicios para el backend; nunca como el único control de seguridad.
Fase 10: Criptografía y aleatoriedad
- Utilizar primitivas criptográficas proporcionadas por la plataforma (Java Cryptography Architecture, Android Keystore); no crear algoritmos personalizados.
- Utilizar modos AEAD modernos como AES-GCM/ChaCha20-Poly1305 para el cifrado autenticado.
- Utilizar Funciones de Derivación de Claves (KDF) establecidas (PBKDF2/HKDF) con parámetros y sales adecuadas.
- Generar claves/Vectores de Inicialización (IVs) con un RNG seguro (
SecureRandomo APIs de la plataforma). - Nunca reutilizar IVs/nonces.
- Mantener las claves en el Keystore o cifradas en reposo.
Fase 11: Permisos, notificaciones e identificadores
- Solicitar los permisos mínimos, en el momento de uso, con explicaciones claras en contexto sobre su valor para el usuario.
Permisos relacionados con la privacidad
- Limitar el acceso a ubicación, contactos, cámara, micrófono, almacenamiento y estado del teléfono a la estricta necesidad.
- Gestionar las denegaciones y revocaciones con elegancia.
- Evitar patrones oscuros (dark patterns) que presionan a los usuarios.
Identificadores y seguimiento
- Preferir identificadores vinculados a la aplicación o restablecibles; evitar construir perfiles (fingerprinting) persistentes entre aplicaciones.
- Utilizar identificadores de publicidad o análisis solo según las políticas de la plataforma.
- Nunca utilizar identificadores de hardware prohibidos para seguimiento.
Notificaciones
- Minimizar los datos sensibles en el contenido de las notificaciones.
- Utilizar una redacción genérica y ocultar los detalles en la pantalla de bloqueo cuando sea posible.
Fase 12: Registros, analíticas (analytics) e informes de fallos
- Utilizar registros estructurados con niveles de gravedad; desactivar registros detallados/de depuración en compilaciones de producción.
- Ocultar PII y secretos de registros, eventos analíticos e informes de fallos.
- Agregar y muestrear analíticas cuando sea posible.
- Asegurar que los archivos de símbolos/mapeo de las compilaciones ofuscadas se guarden de forma segura en el servidor para desofuscar fallos.
- No enviar archivos de símbolos/mapeo dentro de la aplicación.
Fase 13: Pruebas, DAST y verificación en tiempo de ejecución
Pruebas de intercepción de tráfico
- Verificar la resistencia a MITM (certificados no válidos, nombres de host no coincidentes, CAs no confiables).
- Verificar que la fijación (pinning) bloquea la intercepción cuando está configurada.
Inspección en tiempo de ejecución
- Confirmar que no aparezcan secretos/PII en los registros.
- Verificar que los datos sensibles estén cifrados en reposo.
- Revisar el comportamiento del WebView en tiempo de ejecución (navegación, JS, almacenamiento).
- Revisar el comportamiento del almacenamiento local en tiempo de ejecución (archivos, SharedPreferences, bases de datos).
- Validar que las claves respaldadas por Keystore se utilizan donde se espera.
- Validar que los controles de acceso a las claves del Keystore se comportan como se diseñó.
Pruebas de abuso de API
- Probar la limitación de la tasa de peticiones (rate limiting).
- Probar la protección contra ataques de repetición (replay protection).
- Probar los límites de paginación.
- Probar la asignación masiva (mass assignment).
- Probar la higiene de los mensajes de error en APIs backend.
Análisis dinámico
- Ejecutar DAST móvil al realizar los flujos principales para descubrir configuraciones erróneas de transporte, problemas con el WebView, fugas de almacenamiento y problemas de registros.
- Exportar evidencia de DAST para clasificación y re-pruebas.
Fase 14: SBOM y evidencia
SBOM y dependencias
- Generar un SBOM para todos los módulos de Gradle y SDKs incrustados.
- Hacer seguimiento de CVEs y actualizar dependencias regularmente.
- Monitorear el estado de salud de las dependencias como parte de la preparación para el lanzamiento.
- Monitorear el cumplimiento de licencias como parte de la preparación para el lanzamiento.
Paquete de evidencia
- Adjuntar artefactos de escaneo al registro de lanzamiento.
- Adjuntar SBOM al registro de lanzamiento.
- Adjuntar diferencias (diffs) de manifest al registro de lanzamiento.
- Adjuntar listas de permisos y componentes exportados al registro de lanzamiento.
- Adjuntar informes de pruebas automatizadas/manuales al registro de lanzamiento.
Fase 15: Informes y alineación con estándares
Informe
- Proporcionar un resumen ejecutivo, alcance/metodología, hallazgos detallados con PoCs/evidencias, calificaciones de riesgo, guía de remediación y resultados de re-pruebas.
Mapeo de estándares (ejemplo)
- ARCH: Fases 1–2
- PLATFORM: Fases 2, 7–8, 11
- STORAGE: Fases 3–4
- CRYPTO: Fase 10
- AUTH: Fase 6
- NETWORK: Fase 5
- CODE: Fases 2, 9, 12
- RESILIENCE: Fase 9
Referencia rápida para el profesional
- Manifest/Network: Sin tráfico en texto claro en producción; dominios
networkSecurityConfigestrictos; evitar exportar componentes sin una sólida justificación. - Secretos y almacenamiento: Utilizar Keystore de Android para claves de larga duración; cifrar BD/archivos; nunca almacenar secretos en
SharedPreferenceso registros. - Network: Solo HTTPS; fijación (pinning) de certificados/SPKI con respaldos para los endpoints críticos; verificar que los intentos de MITM fallan.
- Auth: OIDC + PKCE; tokens de acceso de corta duración; tokens de actualización en almacenamiento cifrado; autorización del lado del servidor; probar IDOR/BOLA.
- WebView: Preferir navegador para autenticación; si es WebView, JS desactivado por defecto, restringir interfaces, listas de permitidos para navegación, almacenamiento no persistente para flujos sensibles.
- Privacidad: Usar
FLAG_SECUREpara pantallas sensibles; evitar secretos en el portapapeles; minimizar permisos y brindar explicaciones claras. - Higiene de lanzamiento: Ofuscar y reducir código; eliminar registros/menús de depuración y endpoints de prueba; validar permisos y componentes exportados en cada lanzamiento.