iOS Security Review
Expert iOS security skill focused on identifying and remediating vulnerabilities in iOS applications. Prevents security issues before they reach production and App Store review.
When to Apply
ALWAYS activate when:
- Implementing authentication or authorization logic
- Handling sensitive user data (PII, credentials, financial)
- Working with Keychain, Data Protection, or Secure Enclave
- Creating or modifying network requests
- Implementing biometric authentication
- Integrating third-party SDKs
- Handling payments (StoreKit, Apple Pay)
- Adding deep links or URL scheme handling
- Working with WebView (WKWebView)
IMMEDIATELY activate when:
- Security incident or vulnerability reported
- Dependency has a known CVE
- App Store rejection for privacy or security reasons
- Preparing for App Store submission
Quick Reference
Severity Levels
| Level | Examples | Action |
|---|---|---|
| CRITICAL | Hardcoded secrets, unencrypted credentials, disabled ATS | Fix before ANY commit |
| HIGH | Missing SSL pinning, insecure storage, no server-side auth validation | Fix before release |
| MEDIUM | Missing rate limiting, weak input validation, no certificate pinning | Fix in next sprint |
| LOW | Missing obfuscation, verbose logging, best practice gaps | Add to backlog |
iOS Security Feature Requirements
| Feature | Minimum iOS |
|---|---|
| Privacy Manifest | iOS 17.0 |
| evaluatedPolicyDomainState | iOS 16.0 |
| StoreKit 2 (JWS verification) | iOS 15.0 |
| App Attest | iOS 14.0 |
| ASWebAuthenticationSession | iOS 12.0 |
| Biometric (Face ID / Touch ID) | iOS 8.0 |
Mandatory Checks Checklist (Before Every Commit)
Data Security:
- No hardcoded secrets (API keys, tokens, credentials)
- Keychain used for all sensitive data (with correct accessibility level)
- Data Protection enabled for sensitive files
- In-memory sensitive data cleared after use
- No secrets in UserDefaults or Info.plist
Network Security:
- ATS enabled (no
NSAllowsArbitraryLoadswithout justification) - SSL pinning for critical APIs
- Ephemeral sessions for sensitive requests
- No credentials in logs (
print,os_log,NSLog)
Authentication Security:
- Biometric auth includes domain state validation
- Secure token storage in Keychain
- Re-authentication required for sensitive operations
Privacy & Compliance:
- Privacy Manifest up to date (iOS 17+)
- Required Reason APIs documented
- ATT implemented if tracking users
UI Security:
- Screenshot/recording protection for sensitive screens
- Background snapshot blur/hide applied
- Clipboard expiration set for sensitive data
Key Patterns
Keychain Usage (Brief)
// NEVER store sensitive data in UserDefaults
UserDefaults.standard.set(token, forKey: "authToken") // CRITICAL vulnerability
// ALWAYS use Keychain with proper accessibility
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: "authToken",
kSecValueData as String: tokenData,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
SecItemAdd(query as CFDictionary, nil)
Full implementation: see
references/keychain.md
ATS Configuration (Brief)
<!-- Keep ATS enabled (default). Only add exceptions when necessary -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>legacy-api.example.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
</dict>
</dict>
</dict>
Never set NSAllowsArbitraryLoads to true in production.
Full implementation with SSL pinning: see
references/network-security.md
Biometric Authentication (Brief)
let context = LAContext()
context.touchIDAuthenticationAllowableReuseDuration = 0 // Always re-authenticate
// iOS 16+: Detect biometric changes
if let currentState = context.evaluatedPolicyDomainState,
let saved = savedDomainState,
currentState != saved {
throw AuthError.biometricChanged
}
let success = try await context.evaluatePolicy(
.deviceOwnerAuthenticationWithBiometrics,
localizedReason: "Authenticate to access your account"
)
// ALWAYS validate with server after local biometric success
Full implementation: see
references/network-security.md
Privacy Manifest Overview
Every app targeting iOS 17+ must include PrivacyInfo.xcprivacy declaring:
- NSPrivacyTracking -- whether the app tracks users
- NSPrivacyTrackingDomains -- domains used for tracking
- NSPrivacyCollectedDataTypes -- what data is collected and why
- NSPrivacyAccessedAPITypes -- Required Reason APIs used (UserDefaults, file timestamps, etc.)
Full checklist: see
references/review-checklist.md
Security Review Report Format
When performing a security review, produce a report in this structure:
# iOS Security Review Report
**App/Component:** [Name]
**Reviewed:** YYYY-MM-DD
**Reviewer:** ios-security-review skill
## Summary
| Severity | Count |
|----------|-------|
| CRITICAL | X |
| HIGH | Y |
| MEDIUM | Z |
| LOW | W |
**Overall Risk Level:** CRITICAL / HIGH / MEDIUM / LOW
---
## Findings
### [Finding Number]. [Issue Title]
**Severity:** CRITICAL | HIGH | MEDIUM | LOW
**OWASP Category:** M[1-10] - [Category Name]
**Location:** `FileName.swift:LineNumber`
**Issue:**
Description of what is wrong.
**Impact:**
What could happen if this is exploited.
**Remediation:**
[Code fix or configuration change]
**References:**
- OWASP Mobile: M[X]
- Apple Documentation: [Link]
---
## Checklist Results
### Data Storage
- [ ] No sensitive data in UserDefaults
- [ ] Keychain used with appropriate accessibility
- [ ] Files protected with correct protection class
- [ ] Core Data / SwiftData encrypted if storing sensitive data
### Network
- [ ] ATS enabled, exceptions justified
- [ ] Certificate pinning for sensitive APIs
- [ ] No cleartext traffic
### Authentication
- [ ] Biometrics server-validated
- [ ] Tokens stored securely
- [ ] Session management secure
### Code Quality
- [ ] No hardcoded secrets
- [ ] No debug code in release builds
- [ ] Logging sanitized
### App Store Compliance
- [ ] Privacy manifest complete
- [ ] Required Reason APIs documented
- [ ] Data deletion option provided
Common Mistakes (Top 5 Critical Anti-Patterns)
1. Storing Secrets in UserDefaults
// CRITICAL: UserDefaults is a plain plist -- trivially readable
UserDefaults.standard.set(accessToken, forKey: "accessToken")
UserDefaults.standard.set(password, forKey: "password")
// FIX: Use Keychain
try KeychainManager.shared.save(
tokenData, service: "com.app.auth", account: "accessToken"
)
2. Disabling ATS Globally
<!-- CRITICAL: Allows all cleartext HTTP traffic -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<!-- FIX: Only add per-domain exceptions with documented justification -->
3. Client-Only Biometric Bypass
// CRITICAL: Attacker can patch the binary to skip this check
context.evaluatePolicy(.deviceOwnerAuthentication, ...) { success, _ in
if success { self.showSecureContent() } // No server validation!
}
// FIX: Retrieve server-validated token from Keychain after biometric success
// then validate that token with your backend
4. Logging Sensitive Data
// HIGH: Logs persist and may be collected by crash reporting tools
print("User token: \(token)")
NSLog("API response: \(response)")
// FIX: Use conditional compilation and os_log
#if DEBUG
print("Debug info: \(debugInfo)")
#endif
5. Client-Only Purchase Validation
// CRITICAL: Users can fake purchase state
func purchaseCompleted(_ transaction: SKPaymentTransaction) {
UserDefaults.standard.set(true, forKey: "isPremium") // Tamper-able!
}
// FIX: Always validate receipts server-side
// Use StoreKit 2 JWS verification + server-side App Store Server API
References
- OWASP Mobile Top 10 (2024)
- OWASP Mobile Security Testing Guide
- Apple Security Documentation
- Apple Keychain Services
- App Transport Security
- Privacy Manifest Requirements
- App Store Review Guidelines - Safety
- App Attest
Detailed References
For full implementation details and extended checklists, see:
references/keychain.md-- Keychain implementation, data protection, encryption, secret managementreferences/network-security.md-- ATS, SSL pinning, biometric auth, OAuth, StoreKit, Apple Payreferences/review-checklist.md-- OWASP M1-M10 full checklist, UI security, app integrity, response protocol
Remember: iOS apps handle sensitive user data and often financial transactions. One security vulnerability can lead to user data theft, financial loss, and App Store removal. Be thorough and proactive.