Saltar a contenido

Lista de verificación de seguridad para aplicaciones iOS

Fase 0: Gobernanza, entorno y CI/CD

Aplicar puertas de validación en CI (CI gates)

  • Ejecutar comprobaciones estáticas en cada PR: swiftlint (o equivalente), pruebas unitarias/UI, auditoría de dependencias.
  • Bloquear el lanzamiento ante hallazgos SAST/SCA/DAST Altos/Críticos; cero errores de lint en ramas de lanzamiento.

Manejo de secretos

  • Asegurar que no haya secretos en el código fuente, Info.plist, storyboards o registros.
  • Utilizar un gestor de entorno/secretos para los secretos.
  • Ocultar secretos en las analíticas (analytics).
  • Rotar claves/tokens periódicamente y ante sospecha de filtración.

Evidencia y trazabilidad

  • Archivar informes de escaneo con cada artefacto.
  • Archivar SBOM con cada artefacto.
  • Archivar registros de compilación con cada artefacto.
  • Archivar 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 (ej. Ostorlab).
  • Hacer fallar automáticamente las puertas de validación de CI en caso de problemas Altos/Críticos en SAST/DAST/SCA.

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 y transmisión.
  • Identificar los límites de confianza (dispositivo, Keychain/Archivo, URLSession, WebView, canales de plataforma hacia bibliotecas nativas).
  • 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 (Xcode + Info.plist)

Ajustes de lanzamiento de Xcode (Release settings)

  • Eliminar símbolos y código muerto (dead code).
  • Habilitar la optimización de módulo completo (whole-module optimization).
  • Desactivar los indicadores DEBUG en compilaciones de lanzamiento.
  • Excluir frameworks de prueba/depuración del lanzamiento.
  • Eliminar endpoints de desarrollo e indicadores de características (feature flags) del lanzamiento.

Firma de código y autorizaciones (entitlements)

  • Otorgar solo las autorizaciones necesarias (sin App Groups, uso compartido de Keychain, NFC, Bluetooth, etc. sin usar).
  • Utilizar la firma automática con perfiles de lanzamiento dedicados.
  • Proteger las credenciales de firma (ej. almacén de secretos de CI, controles de acceso).

Seguridad de transporte de la aplicación (App Transport Security - ATS)

  • Establecer NSAllowsArbitraryLoads = false.
  • Preferir TLS 1.2+ únicamente.
  • Utilizar NSExceptionDomains estrictos solo cuando sea necesario y por un tiempo limitado.

Higiene del Info.plist

  • Desactivar el uso compartido de documentos a menos que sea necesario:
  • UIFileSharingEnabled = false
  • LSSupportsOpeningDocumentsInPlace = false
  • Minimizar LSApplicationQueriesSchemes; preferir Universal Links sobre esquemas personalizados.
  • Proporcionar cadenas NS[AppData/AppleEvents/SystemAdministration]UsageDescription precisas para todos los permisos.

Fase 3: Almacenamiento local y seguridad del Keychain

Uso del Keychain

  • Almacenar tokens/secretos en el Keychain con la clase más sólida posible:
  • kSecAttrAccessibleWhenUnlockedThisDeviceOnly
  • O kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly cuando aplique.
  • Controlar elementos sensibles con indicadores kSecAccessControl (ej. biometryCurrentSet, userPresence) cuando la UX lo permita.
  • Eliminar elementos del Keychain al cerrar sesión.
  • Considerar la vinculación al dispositivo (device-binding) para tokens de alto riesgo.

Protección de archivos y bases de datos

  • Aplicar protección de datos a los archivos: NSFileProtectionComplete (atributos predeterminados o por archivo).
  • Cifrar bases de datos/archivos sensibles (ej. SQLCipher o equivalente).
  • Nunca almacenar secretos en texto claro.

Cachés y datos derivados

  • Evitar persistir PII en cachés/archivos temporales.
  • Purgar datos sensibles de cachés/archivos temporales al cerrar sesión, según sea necesario.
  • Purgar datos sensibles de cachés/archivos temporales en segundo plano, según sea necesario.
  • No escribir secretos en UserDefaults.

Fase 4: Salvaguardas de privacidad (UI, portapapeles, capturas de pantalla)

  • Ocultar la UI sensible cuando se pasa a segundo plano (desenfoque o imagen de reemplazo en sceneWillResignActive / applicationWillResignActive).
  • Detectar la captura de pantalla (UIScreen.main.isCaptured) y ajustar el comportamiento para vistas altamente sensibles.
  • Evitar leer el portapapeles al iniciar la aplicación.
  • Nunca colocar secretos en UIPasteboard.general.

Fase 5: Seguridad de la red y TLS/fijación (pinning)

URLSession/ATS

  • Forzar HTTPS a hosts confiables.
  • Rechazar certificados y nombres de host no válidos.
  • Desactivar los respaldos (fallbacks) a HTTP.
  • Establecer tiempos de espera estrictos.
  • Implementar reintentos con variaciones (jitter) cuando sea apropiado.
  • Fallar por defecto (fail closed) en caso de errores TLS.
  • Forzar el uso de TLS 1.2+ en la configuración TLS del servidor.

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 a través de la evaluación de confianza URLSessionDelegate.
  • Validar el comportamiento contra intentos de MITM.
  • Validar el comportamiento para certificados de hoja expirados/rotados.
  • Planificar la rotación segura de fijaciones.
  • Incluir telemetría sobre fallos de fijación.

Cookies y tokens

  • Utilizar cookies seguras, HttpOnly, SameSite para los flujos web.
  • Evitar tokens de portador (bearer tokens) de larga duración en el dispositivo.
  • Borrar cookies y datos web 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 el navegador del sistema (ASWebAuthenticationSession / SafariViewController) sobre WebView para la autenticación.

Tokens

  • Utilizar tokens de acceso (access tokens) de corta duración.
  • Almacenar tokens de actualización (refresh tokens) en el Keychain.
  • Rotar e invalidar tokens al cerrar sesión.
  • Rotar e invalidar tokens al cambiar de dispositivo.
  • Vincular sesiones al riesgo del dispositivo (device risk) donde sea apropiado.
  • Detectar anomalías (cambios de geo/IP/ASN) y responder a ellas.

Autorización

  • Forzar la autorización en el servidor; tratar las comprobaciones del cliente como consultivas.
  • Validar en busca de vulnerabilidades IDOR/BOLA.
  • Validar en busca de problemas de escalada de privilegios.

Fase 7: Fortalecimiento del WebView (WKWebView)

  • Utilizar WKWebView solo cuando sea requerido.
  • Preferir dominios limitados a la aplicación para el aislamiento (WKAppBoundDomains).

Valores predeterminados

  • Desactivar JavaScript a menos que sea necesario.
  • Desactivar javaScriptCanOpenWindowsAutomatically.
  • Establecer listas de permitidos para la navegación a través de WKNavigationDelegate.
  • Bloquear URLs file://.
  • Bloquear URLs javascript:.
  • Utilizar un almacén de datos no persistente para sesiones sensibles.
  • Borrar HTTPCookieStore y los datos del sitio web al cerrar sesión.
  • Asegurarse de que el Web Inspector esté deshabilitado en el lanzamiento (iOS 16+ isInspectable = false).

Seguridad del contenido

  • Para el contenido web propio, aplicar la política CSP.
  • Forzar HTTPS.
  • No permitir contenido mixto.

  • Preferir los Universal Links.
  • Validar los orígenes y parámetros de los enlaces entrantes.

Si se utilizan esquemas de URL personalizados

  • Elegir un esquema único.
  • Validar todos los parámetros.
  • Defenderse del secuestro de URL.
  • Defenderse de redireccionamientos abiertos.
  • Limitar LSApplicationQueriesSchemes a los esquemas conocidos y necesarios.

Fase 9: Ingeniería inversa y resistencia a la manipulación (tampering)

Reducir filtraciones estáticas

  • Eliminar los símbolos de los binarios enviados a la tienda.
  • Almacenar dSYMs en el lado del servidor para la simbolización de fallos.
  • Eliminar registros detallados en compilaciones de lanzamiento.
  • Eliminar menús de depuración en compilaciones de lanzamiento.
  • Eliminar endpoints de prueba en compilaciones de lanzamiento.
  • Eliminar alternadores de funciones (feature toggles) no destinados a producción.

Controles de entorno

  • Registrar señales sobre la presencia de jailbreak (archivos, llamadas al sistema, bibliotecas sospechosas).
  • Registrar señales sobre frameworks de hooking.
  • Registrar señales sobre la presencia de un depurador.
  • Responder de forma proporcional (degradación/bloqueo/telemetría) sin basarse únicamente en controles del cliente.

Pruebas de manipulación (Tamper testing)

  • Validar que las compilaciones reempaquetadas fallen en los controles de integridad o en la certificación del servidor.
  • Validar que las compilaciones re-firmadas fallen en los controles de integridad o en la certificación del servidor.
  • Tratar los controles del lado del cliente como señales, nunca como el único control de seguridad.

Fase 10: Criptografía y aleatoriedad

  • Utilizar criptografía de plataforma (CryptoKit / CommonCrypto); no implementar criptografía personalizada.
  • Utilizar AES-GCM o ChaCha20-Poly1305 para el cifrado autenticado.
  • Utilizar HKDF/PBKDF2 como KDF con la sal adecuada y parámetros adecuados.
  • Generar claves/IVs con SecRandomCopyBytes.
  • Nunca reutilizar IVs/nonces.
  • Almacenar las claves criptográficas en el Keychain.

Fase 11: Permisos, notificaciones e identificadores

  • Solicitar los permisos mínimos requeridos.
  • Solicitar permisos en el momento de uso.
  • Explicar claramente la propuesta de valor a los usuarios al solicitar permisos.

ATT (App Tracking Transparency)

  • Solicitar ATT solo si es necesario.
  • Degradar de forma elegante si se deniega el ATT.
  • Evitar el fingerprinting y técnicas de seguimiento prohibidas similares.

Identificadores

  • Preferir identifierForVendor.
  • Evitar IDFA a menos que se haya otorgado ATT.
  • Nunca usar identificadores persistentes prohibidos.

Fase 12: Registros, analíticas (analytics) e informes de fallos

  • Utilizar os_log con anotaciones de privacidad.
  • Desactivar los registros detallados en compilaciones de lanzamiento.
  • Ocultar PII de los registros.
  • Ocultar secretos de los registros.
  • Ocultar PII y secretos de los eventos analíticos.
  • Ocultar PII y secretos de los informes de fallos.
  • Muestrear y agregar analíticas donde sea posible.
  • Asegurarse de que la simbolización de fallos se produzca del lado del servidor.
  • Nunca incluir símbolos con 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 con un certificado no válido.
  • Verificar la resistencia a MITM con nombres de host no coincidentes.
  • Verificar la resistencia a MITM con una CA no confiable.
  • Confirmar que la fijación (pinning) bloquea la intercepción donde se implementa.

Inspección en tiempo de ejecución

  • Confirmar que no haya secretos/PII en los registros.
  • Confirmar que los elementos del Keychain están presentes con las ACL (Listas de Control de Acceso) correctas.
  • Confirmar que los archivos tienen NSFileProtectionComplete (o más estricto cuando sea necesario).

Pruebas de abuso de API

  • Probar la limitación de la tasa de peticiones (rate limiting).
  • Probar las protecciones contra ataques de repetición (replay protections).
  • Probar los límites de paginación.
  • Probar si hay vulnerabilidades de asignación masiva (mass assignment).
  • Probar si hay fugas detalladas de errores.

Análisis dinámico

  • Ejecutar DAST móvil al ejercitar los flujos principales para descubrir configuraciones erróneas de transporte.
  • Utilizar DAST para descubrir problemas de ejecución (ej. con Ostorlab).
  • Exportar evidencia para clasificación y re-pruebas.

Fase 14: SBOM y evidencia

SBOM y dependencias

  • Generar SBOM para el código Swift/Objective-C.
  • Generar SBOM para SDKs incrustados.
  • Realizar seguimiento de los CVEs que afectan a las dependencias.
  • Actualizar dependencias periódicamente en función del riesgo.

Paquete de evidencia

  • Adjuntar artefactos de escaneo al lanzamiento.
  • Adjuntar SBOM al lanzamiento.
  • Adjuntar diferencias (diffs) de Info.plist al lanzamiento.
  • Adjuntar listas de autorizaciones (entitlements) al lanzamiento.
  • Adjuntar informes de pruebas al lanzamiento.

Fase 15: Informes y alineación con estándares

Informe

  • Elaborar un resumen ejecutivo.
  • Documentar el alcance y la metodología.
  • Documentar hallazgos detallados con PoCs y evidencia.
  • Asignar calificaciones de riesgo a los hallazgos.
  • Proporcionar orientación para la corrección.
  • Incluir resultados de re-pruebas.

Mapeo con OWASP MASVS

  • 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

  • Info.plist/ATS: Sin cargas arbitrarias; dominios de excepción estrictos; deshabilitar uso compartido de documentos/archivos a menos que sea necesario.
  • Keychain: Clases ThisDeviceOnly; biometryCurrentSet/userPresence opcional; eliminar secretos al cerrar sesión.
  • Archivos: NSFileProtectionComplete; cifrar bases de datos/archivos; evitar UserDefaults para los secretos.
  • Network: Solo HTTPS; fijación mediante URLSessionDelegate (SPKI SHA-256 con respaldos); verificar que los intentos de MITM fallan.
  • Auth: OIDC + PKCE; tokens de corta duración; tokens de actualización en el Keychain; autorización del lado del servidor; probar IDOR/BOLA.
  • WebView: Preferir el navegador del sistema para la autenticación; si es WKWebView, JS desactivado por defecto, permitir navegación en listas, dominios vinculados a la aplicación, almacenamiento no persistente para flujos sensibles.
  • Privacidad: Enmascarar instantáneas de fondo; evitar secretos en el portapapeles; minimizar permisos y mantener cadenas de uso precisas.
  • Higiene de lanzamiento: Eliminar símbolos en la aplicación, mantener dSYMs privados; eliminar registros/menús de depuración; validar autorizaciones (entitlements).

Configuraciones y fragmentos de ejemplo

ATS (Info.plist)

  • Configurar NSAppTransportSecurity:
  • NSAllowsArbitraryLoads = false
  • NSExceptionDomains = { yourdomain.com: { NSTemporaryExceptionAllowsInsecureHTTPLoads = false, NSIncludesSubdomains = true, NSTemporaryExceptionMinimumTLSVersion = TLSv1.2 } }

Protección de archivos (Swift)

  • Utilizar la protección completa de archivos:
  • try data.write(to: url, options: .completeFileProtection)

Elemento del Keychain (ejemplo en Swift)

  • Configurar el elemento del Keychain:
  • kSecClass: kSecClassGenericPassword
  • kSecAttrAccessible: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
  • kSecAttrAccessControl: SecAccessControlCreateWithFlags(..., [.biometryCurrentSet, .userPresence])

Fijación de URLSession (resumen)

  • En urlSession(_:didReceive:completionHandler:):
  • Evaluar SecTrust.
  • Extraer SPKI del certificado.
  • Comparar SHA-256 del SPKI con una lista de permitidos de pines.
  • Elegir .useCredential o .cancel adecuadamente.

Flujos de trabajo ligeros

Puerta de validación previa a la fusión (Pre-merge gate)

  • Ejecutar lints y pruebas.
  • Ejecutar auditoría de dependencias.
  • Desencadenar escaneos SAST/SCA.
  • Bloquear la fusión ante problemas Altos/Críticos.

Entorno de ensayo previo al lanzamiento (Pre-release staging)

  • Validar Info.plist y autorizaciones (entitlements).
  • Compilar el binario de lanzamiento.
  • Confirmar que los símbolos no se envían en la aplicación.
  • Ejecutar DAST al ejercitar los principales flujos de usuario (ej. con Ostorlab) para validar TLS/fijación, la protección de almacenamiento y la higiene de registros.
  • Solucionar problemas y volver a probar.

Monitoreo posterior al lanzamiento (Post-release monitoring)

  • Realizar seguimiento de fallos y rendimiento.
  • Rotar claves/tokens en un cronograma definido.
  • Monitorear advertencias de seguridad sobre SDKs y CVEs.
  • Mantener SCA vigilando SDKs/bibliotecas de terceros (ej. Ostorlab) para alertar sobre nuevas vulnerabilidades.
  • Desencadenar re-pruebas focalizadas cuando se encuentren nuevas vulnerabilidades.