Swift 应用安全:十大常见漏洞实战解析

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Swift 应用安全:十大常见漏洞实战解析



iOS 和 macOS 移动应用的开发需要特别关注安全性。Swift 是一种强大且现代的语言,但即使如此,它也无法保护开发者免受典型错误的影响,这些错误可能导致数据泄露、黑客攻击或财务损失。在本文中,我们将通过真实的代码示例和实用的修复建议,解析 Swift 应用的十大常见漏洞。



1. 通过 Core Data 和 SQLite 进行 SQL 注入

许多开发者在使用 SQLite 时会编写原始 SQL 查询。如果用户输入的数据未经过转义,攻击者就可以对数据库执行任意查询。

// ❌ 有漏洞的代码let query = "SELECT * FROM users WHERE name = '\\(userInput)'"

// ✅ 安全的代码(使用参数化查询)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)

请使用参数化查询或带有谓词的 Core Data——这可以杜绝注入攻击。



2. Keychain 中不安全的存储

Keychain 是一个安全的位置,但许多开发者错误地配置了访问属性。例如,如果不指定 kSecAttrAccessible,数据可能在备份后仍可访问。

// ❌ 有漏洞的代码(备份后可访问)let query: [String: Any] = [    kSecClass as String: kSecClassGenericPassword,    kSecAttrAccount as String: "token",    kSecValueData as String: tokenData]

// ✅ 安全的代码(仅在设备解锁时可用)let query: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrAccount as String: "token", kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly, kSecValueData as String: tokenData]


3. 缺少 SSL/TLS 验证(中间人攻击)

在开发过程中,为了测试,开发者常常会禁用证书验证,但忘记在发布版本中恢复设置。这使得攻击者能够拦截流量。

// ❌ 有漏洞的代码(对生产环境危险)let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)// 在代理中:func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {    completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))}

// ✅ 安全的代码——使用标准验证let session = URLSession.shared// 或者在 Info.plist 中使用 ATS(App Transport Security)

请启用 App Transport Security (ATS),并且不要在发布版本中禁用它。



4. 通过日志和 Crashlytics 泄露数据

开发者经常为了调试而记录敏感数据(令牌、密码)。如果日志落入第三方服务(例如 Firebase Crashlytics),数据就会泄露。

// ❌ 有漏洞的代码print("User token: \\(userToken)")

// ✅ 安全的代码#if DEBUG print("User token: [REDACTED]")#endif// 或者使用带有隐私级别的 os_logos_log("User token: %{private}@", log: .default, type: .debug, userToken)

切勿在生产环境中记录敏感数据。请使用掩码或条件编译。



5. 在代码中不安全地存储密钥

将 API 密钥、令牌和密码直接存储在源代码中是一个严重的错误。即使代码被混淆,字符串也很容易从二进制文件中提取。

// ❌ 有漏洞的代码let apiKey = "sk-1234567890abcdef"

// ✅ 安全的代码——使用服务器端身份验证// 或者使用 CryptoKit 加密密钥import CryptoKitlet key = SymmetricKey(data: "server_

博客

书籍推荐