Introducción: Por qué la seguridad en aplicaciones Swift es crítica
Swift es un lenguaje de programación moderno y potente creado por Apple para desarrollar aplicaciones para iOS, macOS, watchOS y tvOS. A pesar de los mecanismos de seguridad integrados (ARC, gestión segura de memoria, tipos opcionales), miles de aplicaciones son víctimas de ataques cada año debido a errores de los desarrolladores. Según el informe OWASP Mobile Top 10, la mayoría de las vulnerabilidades en aplicaciones móviles ocurren en el lado del cliente. En este artículo, analizaremos las 10 vulnerabilidades más comunes en aplicaciones Swift, proporcionaremos ejemplos de código y mostraremos cómo evitarlas.
1. Almacenamiento inseguro de datos
Problema
Los desarrolladores suelen guardar datos confidenciales (tokens, contraseñas, claves API) en UserDefaults, archivos Plist o Core Data sin cifrado. En dispositivos con jailbreak, un atacante puede acceder fácilmente a ellos.
Ejemplo de código vulnerable
// Código vulnerableUserDefaults.standard.set("secret_token_123", forKey: "api_token")UserDefaults.standard.set("password123", forKey: "user_password")Solución
Utiliza Keychain para almacenar datos sensibles. Swift cuenta con envoltorios convenientes como KeychainSwift o el framework Security.
// Almacenamiento seguro con Keychainimport KeychainSwift
let keychain = KeychainSwift()keychain.set("secret_token_123", forKey: "api_token")keychain.set("password123", forKey: "user_password", withAccess: .accessibleWhenUnlockedThisDeviceOnly)2. Inyección de código e inyección SQL
Problema
Si tu aplicación usa SQLite, Core Data con NSPredicate o WebView para mostrar contenido web, un atacante puede inyectar código malicioso a través de la entrada del usuario.
Ejemplo de código vulnerable
// Consulta SQLite vulnerablelet userInput = "1' OR '1'='1"let query = "SELECT * FROM users WHERE id = '\\(userInput)'"Solución
Utiliza consultas parametrizadas o NSPredicate con sustituciones seguras.
// Consulta segura con parámetroslet query = "SELECT * FROM users WHERE id = ?"let statement = try db.prepare(query)try statement.bind(1, userInput)3. Comunicación de red insegura
Problema
Usar HTTP en lugar de HTTPS, ignorar certificados SSL (App Transport Security) o enviar datos sin cifrado.
Ejemplo de código vulnerable
// Código vulnerable: deshabilitando ATSlet url = URL(string: "http://example.com/api/login")!let task = URLSession.shared.dataTask(with: url) { data, response, error in // Procesando datos no seguros}Solución
Configura App Transport Security (ATS) en Info.plist y usa HTTPS. Para la verificación de certificados, aplica SSL pinning.
// Solicitud segura con SSL Pinning (ejemplo con Alamofire)let evaluator = PinnedCertificatesTrustEvaluator(certificates: [certificate])let session = Session(serverTrustManager: ServerTrustManager(evaluators: ["example.com": evaluator]))session.request("https://example.com/api/login").responseJSON { response in // Procesando datos seguros}4. Inyección en WebView
Problema
Cargar contenido HTML con datos del usuario en WKWebView sin sanitización puede provocar ataques XSS y robo de cookies.
Ejemplo de código vulnerable
// Código vulnerablelet userComment = "<script>alert('XSS')</script>"let html