Segurança de aplicativos Swift: top 10 vulnerabilidades para iniciantes
\n\nDesenvolver em Swift para iOS e macOS exige atenção especial à segurança. Mesmo pequenos erros podem levar a vazamento de dados ou invasão do aplicativo. Neste artigo, analisaremos as 10 vulnerabilidades mais comuns enfrentadas por desenvolvedores iniciantes e mostraremos como evitá-las.
\n\n1. Armazenamento inseguro de dados no UserDefaults
\nMuitos iniciantes salvam dados confidenciais (senhas, tokens) no UserDefaults. Esta é uma área de uso comum, os dados são armazenados em texto aberto.
// ❌ Perigoso\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. Injeções SQL no Core Data
\nUsar predicados de string com entrada do usuário abre caminho para injeções SQL.
\n// ❌ Vulnerável\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. Ausência de validação de entrada
\nConfiar na entrada do usuário é um dos maiores erros. Um invasor pode enviar dados maliciosos através de campos de texto.
\nfunc processUserInput(_ text: String) {\n // ❌ Permitimos qualquer entrada\n let url = URL(string: "https://api.example.com/search?q=\\(text)")\n \n // ✅ Verificamos e 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. Conexão de rede insegura (HTTP em vez de HTTPS)
\nUsar HTTP torna os dados vulneráveis a interceptação. Sempre use HTTPS.
\n// ❌ Perigoso\nlet config = URLSessionConfiguration.default\nconfig.waitsForConnectivity = false\n\n// ✅ Seguro — forçamos HTTPS\nlet config = URLSessionConfiguration.default\nconfig.connectionProxyDictionary?.removeAll()\nconfig.tlsMinimumSupportedProtocolVersion = .TLSv12\n\n\n5. Vazamento de dados através de logs
\nDesenvolvedores frequentemente deixam print() com dados confidenciais na versão de produção.
// ❌ Perigoso\nprint("User token: \\(token)")\n\n// ✅ Seguro — usamos compilação condicional\n#if DEBUG\nprint("Debug: token length = \\(token.count)")\n#endif\n\n\n6. Gerenciamento incorreto de memória (Retain Cycles)
\nVazamentos de memória podem levar a ataques DoS. Use referências fracas em closures.
\n// ❌ Vazamento de memória\nclass ViewController: UIViewController {\n var handler: (() -> Void)?\n override func viewDidLoad() {\n handler = {\n self.view.backgroundColor = .red // Referência forte\n }\n }\n}\n\n// ✅ Seguro — referência fraca\nhandler = { [weak self] in\n self?.view.backgroundColor = .red\n}\n\n\n7. Ausência de verificação de autenticidade de esquemas URL
\nAplicativos fraudulentos podem interceptar os esquemas URL do seu aplicativo.
\n// ❌ Vulnerável\nfunc application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {\n // Processamos qualquer URL\n return true\n}\n\n// ✅ Seguro — verificamos a origem\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 // Processamento da URL\n return true\n}\n\n\n