Swift Application Security: Top 10 Vulnerabilities for Beginners
\n\nDeveloping in Swift for iOS and macOS requires special attention to security. Even small mistakes can lead to data leaks or application hacking. In this article, we will break down the 10 most common vulnerabilities that beginner developers face and show how to avoid them.
\n\n1. Insecure Data Storage in UserDefaults
\nMany beginners save confidential data (passwords, tokens) in UserDefaults. This is a shared area, and data is stored in plain text.
// ❌ Dangerous\nUserDefaults.standard.set("secret_password", forKey: "userPass")\n\n// ✅ Safe — use 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. SQL Injections in Core Data
\nUsing string predicates with user input opens the door to SQL injections.
\n// ❌ Vulnerable\nlet input = "admin' OR '1'='1"\nlet predicate = NSPredicate(format: "name == %@", input)\n\n// ✅ Safe — use parameterized queries\nlet safePredicate = NSPredicate(format: "name == %@", input)\n\n\n3. Lack of Input Validation
\nTrusting user input is one of the main mistakes. An attacker can send malicious data through text fields.
\nfunc processUserInput(_ text: String) {\n // ❌ Passes any input\n let url = URL(string: "https://api.example.com/search?q=\\(text)")\n \n // ✅ Validate and escape\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. Insecure Network Connection (HTTP instead of HTTPS)
\nUsing HTTP makes data vulnerable to interception. Always use HTTPS.
\n// ❌ Dangerous\nlet config = URLSessionConfiguration.default\nconfig.waitsForConnectivity = false\n\n// ✅ Safe — enforce HTTPS\nlet config = URLSessionConfiguration.default\nconfig.connectionProxyDictionary?.removeAll()\nconfig.tlsMinimumSupportedProtocolVersion = .TLSv12\n\n\n5. Data Leakage Through Logs
\nDevelopers often leave print() with confidential data in production builds.
// ❌ Dangerous\nprint("User token: \\(token)")\n\n// ✅ Safe — use conditional compilation\n#if DEBUG\nprint("Debug: token length = \\(token.count)")\n#endif\n\n\n6. Improper Memory Management (Retain Cycles)
\nMemory leaks can lead to DoS attacks. Use weak references in closures.
\n// ❌ Memory leak\nclass ViewController: UIViewController {\n var handler: (() -> Void)?\n override func viewDidLoad() {\n handler = {\n self.view.backgroundColor = .red // Strong reference\n }\n }\n}\n\n// ✅ Safe — weak reference\nhandler = { [weak self] in\n self?.view.backgroundColor = .red\n}\n\n\n7. Lack of URL Scheme Authentication
\nMalicious applications can intercept your app's URL schemes.
\n// ❌ Vulnerable\nfunc application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {\n // Process any URL\n return true\n}\n\n// ✅ Safe — verify the source\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 // URL processing\n return true\n}\n\n\nBlogs
Book Recommendations
Read also
Error Handling in JavaScript: try/catch and Advanced Techniques in Node.js
asyncio Python: How to Use Async/Await for Asynchronous Code