Swift Application Security: Top 10 Vulnerabilities in Practice

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Swift Application Security: Top 10 Vulnerabilities in Practice



Developing mobile applications for iOS and macOS requires special attention to security. Swift is a powerful and modern language, but even it does not protect developers from common mistakes that can lead to data leaks, hacking, or financial losses. In this article, we will break down the top 10 vulnerabilities of Swift applications with real code examples and practical recommendations for fixing them.



1. SQL Injections via Core Data and SQLite

Many developers use raw SQL queries with SQLite. If user input is not sanitized, an attacker can execute arbitrary queries against the database.

// ❌ Vulnerable codelet query = "SELECT * FROM users WHERE name = '\\(userInput)'"

// ✅ Secure code (using parameterized queries)let query = "SELECT * FROM users WHERE name = ?"var statement: OpaquePointer?sqlite3_prepare_v2(database, query, -1, &statement, nil)sqlite3_bind_text(statement, 1, (userInput as NSString).utf8String, -1, nil)

Use parameterized queries or Core Data with predicates — this eliminates injections.



2. Insecure Data Storage in Keychain

Keychain is a secure place, but many developers incorrectly configure access attributes. For example, if kSecAttrAccessible is not specified, data may be accessible after backup.

// ❌ Vulnerable code (accessible after backup)let query: [String: Any] = [    kSecClass as String: kSecClassGenericPassword,    kSecAttrAccount as String: "token",    kSecValueData as String: tokenData]

// ✅ Secure code (only when device is unlocked)let query: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrAccount as String: "token", kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly, kSecValueData as String: tokenData]


3. Missing SSL/TLS Verification (Man-in-the-Middle)

During development, certificate verification is often disabled for testing, but developers forget to restore settings for release. This allows an attacker to intercept traffic.

// ❌ Vulnerable code (dangerous for production)let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)// In the delegate:func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {    completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))}

// ✅ Secure code — use standard verificationlet session = URLSession.shared// Or use ATS (App Transport Security) in Info.plist

Enable App Transport Security (ATS) and do not disable it in the release build.



4. Data Leakage via Logs and Crashlytics

Developers often log sensitive data (tokens, passwords) for debugging. If the log ends up in a third-party service (e.g., Firebase Crashlytics), data leaks.

// ❌ Vulnerable codeprint("User token: \\(userToken)")

// ✅ Secure code#if DEBUG print("User token: [REDACTED]")#endif// Or use os_log with privacy levelos_log("User token: %{private}@", log: .default, type: .debug, userToken)

Never log sensitive data in production. Use masking or conditional compilation.



5. Insecure Storage of Secrets in Code

Storing API keys, tokens, and passwords directly in source code is a critical mistake. Even if the code is obfuscated, strings can be easily extracted from the binary file.

// ❌ Vulnerable codelet apiKey = "sk-1234567890abcdef"

// ✅ Secure code — use server-side authentication// Or encrypt keys using CryptoKitimport CryptoKitlet key = SymmetricKey(data: "server_

Blogs

Book Recommendations