Seguridad en aplicaciones Swift: top 10 vulnerabilidades para principiantes
\n\nDesarrollar en Swift para iOS y macOS requiere especial atención a la seguridad. Incluso pequeños errores pueden provocar fugas de datos o la piratería de la aplicación. En este artículo analizaremos las 10 vulnerabilidades más comunes que enfrentan los desarrolladores principiantes y mostraremos cómo evitarlas.
\n\n1. Almacenamiento inseguro de datos en UserDefaults
\nMuchos novatos guardan datos confidenciales (contraseñas, tokens) en UserDefaults. Esta es una zona de uso común, los datos se almacenan en texto plano.
// ❌ Peligroso\nUserDefaults.standard.set("secret_password", forKey: "userPass")\n\n// ✅ Seguro — usamos Keychain\nimport Security\nlet query: [String: Any] = [\n kSecClass as String: kSecClassGenericPassword,\n kSecAttrAccount as String: "userPass",\n kSecValueData as String: "secret_password".data(using: .utf8)!\n]\nSecItemAdd(query as CFDictionary, nil)\n\n\n2. Inyecciones SQL en Core Data
\nEl uso de predicados de cadena con entrada del usuario abre el camino a inyecciones SQL.
\n// ❌ Vulnerable\nlet input = "admin' OR '1'='1"\nlet predicate = NSPredicate(format: "name == %@", input)\n\n// ✅ Seguro — usamos consultas parametrizadas\nlet safePredicate = NSPredicate(format: "name == %@", input)\n\n\n3. Falta de validación de entrada
\nConfiar en la entrada del usuario es uno de los principales errores. Un atacante puede enviar datos maliciosos a través de campos de texto.
\nfunc processUserInput(_ text: String) {\n // ❌ Permitimos cualquier entrada\n let url = URL(string: "https://api.example.com/search?q=\\(text)")\n \n // ✅ Verificamos y escapamos\n guard let encoded = text.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { return }\n let safeUrl = URL(string: "https://api.example.com/search?q=\\(encoded)")\n}\n\n\n4. Conexión de red insegura (HTTP en lugar de HTTPS)
\nEl uso de HTTP hace que los datos sean vulnerables a la interceptación. Use siempre HTTPS.
\n// ❌ Peligroso\nlet config = URLSessionConfiguration.default\nconfig.waitsForConnectivity = false\n\n// ✅ Seguro — forzamos HTTPS\nlet config = URLSessionConfiguration.default\nconfig.connectionProxyDictionary?.removeAll()\nconfig.tlsMinimumSupportedProtocolVersion = .TLSv12\n\n\n5. Fuga de datos a través de registros
\nLos desarrolladores a menudo dejan print() con datos confidenciales en la compilación de producción.
// ❌ Peligroso\nprint("User token: \\(token)")\n\n// ✅ Seguro — usamos compilación condicional\n#if DEBUG\nprint("Debug: token length = \\(token.count)")\n#endif\n\n\n6. Gestión incorrecta de memoria (Ciclos de retención)
\nLas fugas de memoria pueden provocar ataques DoS. Use referencias débiles en closures.
\n// ❌ Fuga de memoria\nclass ViewController: UIViewController {\n var handler: (() -> Void)?\n override func viewDidLoad() {\n handler = {\n self.view.backgroundColor = .red // Referencia fuerte\n }\n }\n}\n\n// ✅ Seguro — referencia débil\nhandler = { [weak self] in\n self?.view.backgroundColor = .red\n}\n\n\n7. Falta de verificación de autenticidad de esquemas URL
\nLas aplicaciones fraudulentas pueden interceptar los esquemas URL de su aplicación.
\n// ❌ Vulnerable\nfunc application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {\n // Procesamos cualquier URL\n return true\n}\n\n// ✅ Seguro — verificamos el origen\nfunc application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {\n guard let sourceApp = options[.sourceApplication] as? String,\n sourceApp == "com.trusted.app" else {\n return false\n }\n // Procesamiento de URL\n return true\n}\n\n\nBlogs
Book Recommendations
Leer también
Presente y futuro de la IA: la matemática clásica ya no es suficiente