Security Checklist
OWASP Mobile Top 10 mapped to iOS, with the actual mitigation. Run this list before every release; do a deep audit annually or after major architectural changes.
M1: Improper Credential Usage
Risk: Hardcoded credentials, plaintext credentials in storage, credentials in logs.
iOS mitigations:
- No API keys, secrets, tokens checked into source
-
Secrets injected via build config or fetched at runtime (xcconfig +
.gitignore) - User credentials (passwords, tokens) stored in Keychain only — never UserDefaults
-
Keychain items use
kSecAttrAccessibleWhenUnlockedThisDeviceOnly(most restrictive that fits) -
No tokens / passwords in
os_logorprint(use.privatefor sensitive log args) - No tokens / passwords in error messages shown to user
M2: Inadequate Supply Chain Security
Risk: A compromised SDK / SPM dependency ships malicious code.
iOS mitigations:
-
Pin dependencies to exact versions (
Package.resolvedcommitted) - Review every new dependency before adoption (popularity, last commit, maintainers)
- Audit third-party SDKs for unexpected network calls (use Charles / mitmproxy in dev)
- Verify privacy manifests of SDKs match what they’re permitted to do
- Subscribe to security advisories for each major dependency
-
CI build runs
swift package show-dependenciesand alerts on changes
M3: Insecure Authentication / Authorization
Risk: Weak auth flows, predictable session tokens, missing authorization checks.
iOS mitigations:
- OAuth2 / OIDC for any third-party auth; never roll your own
- Use Sign in with Apple where appropriate (privacy-friendly, supported by Apple)
- Tokens short-lived; refresh tokens rotated
- Biometric (FaceID / TouchID) protection for sensitive operations via LocalAuthentication
- Server enforces authorization on every endpoint (never trust client-side checks)
- Sign-out clears Keychain entries
M4: Insufficient Input/Output Validation
Risk: Server returns unexpected data; user input not sanitized.
iOS mitigations:
-
All server responses decoded through
Codabletypes (fails fast on schema drift) - User input length-limited at the UI
-
URL inputs validated before opening (avoid arbitrary
URL-based code paths) - Deep link / universal link payloads validated and bounded
- WKWebView-loaded URLs whitelisted to your domains
M5: Insecure Communication
Risk: HTTP, weak TLS, MITM-able traffic.
iOS mitigations:
-
ATS (App Transport Security) enabled by default (no
NSAllowsArbitraryLoads) - Per-domain exceptions justified and minimal
- HTTPS-only for all network calls
-
Certificate pinning for highest-value endpoints (e.g., auth, payments) via
URLSessionDelegate - TLS 1.2 minimum (1.3 if possible)
-
Don’t trust user-installed CA certificates for critical endpoints (set
serverTrustpolicy)
M6: Inadequate Privacy Controls
Risk: User data collected without consent or beyond stated use.
iOS mitigations:
- Privacy Nutrition Label completed accurately in App Store Connect
-
PrivacyInfo.xcprivacyreflects actual API usage - App Tracking Transparency prompt shown before any tracking
- No collection of data beyond what’s declared
- Analytics events scrubbed of PII
- User can delete their account and data (required by App Store guideline 5.1.1(v))
M7: Insufficient Binary Protections
Risk: Reverse engineering, tampering, jailbreak abuse.
iOS mitigations:
- App built with optimization (Release config) — symbols and SwiftUI bodies are not directly readable
-
No debugger attached check for highly sensitive apps (sysctl
KERN_PROC+P_TRACED) - Code signing verified at install (Apple does this)
- Don’t waste time on obfuscation — App Store binaries are reasonably protected; focus on server-side checks
M8: Security Misconfiguration
Risk: Debug settings enabled in production, verbose errors, unsafe defaults.
iOS mitigations:
-
No
print()of sensitive data in Release builds -
No debugging UI accessible in Release builds (use
#if DEBUG) - Crash reports scrubbed of PII before transmission
- App Group permissions reviewed (only the extensions that need access)
- No development entitlements in production binaries
M9: Insecure Data Storage
Risk: Sensitive data on disk in plaintext or world-readable locations.
iOS mitigations:
- Sensitive data only in Keychain
-
Files stored with
.completeUntilFirstUserAuthenticationor.completeprotection - Photos / videos containing personal info stored in the app sandbox, not Photos library
- SQLite / SwiftData files in protected directories
-
No sensitive data in
NSTemporaryDirectory()without cleanup -
Pasteboard not used for sensitive transfers (use
UIPasteboardOptions.localOnlyif needed)
M10: Insufficient Cryptography
Risk: Weak algorithms, custom crypto, bad key management.
iOS mitigations:
-
Use CryptoKit (Apple’s modern API) —
AES.GCM,Curve25519,SHA256 - No custom crypto algorithms
- Keys derived from passwords use PBKDF2 / Argon2 with sufficient iterations
-
Symmetric keys stored in Keychain or Secure Enclave (
SecureEnclave.P256.Signing.PrivateKey) - No deprecated algorithms (MD5, SHA1, DES, ECB)
-
Random values from
SecRandomCopyBytesor CryptoKit, neverarc4random()for cryptographic purposes
Bonus — iOS-specific security hygiene
- Pasteboard usage minimized (system shows banner when read in iOS 16+)
-
Universal links validated against
apple-app-site-association - URL schemes documented and limited
-
Custom keyboards disallowed for password fields (
.textContentType(.password)discourages 3rd-party keyboards) -
Screenshot in app switcher hidden for sensitive content (
SceneDelegateblurs on background) - FaceID / TouchID prompt before showing sensitive screens after backgrounding
- Background tasks complete or are cancelled cleanly (no lingering work that could expose data)
CI/CD security
- CI secrets stored as GitHub Actions / similar encrypted secrets — never in repo
- Signing certificates in CI use temporary keychains per build (cleaned after)
- App Store Connect API key restricted to needed scopes
- Production deploys gated behind required approvals
- Audit log of who deployed what, when
Annual review
Once a year, do a full security audit:
- Re-run this checklist
- Audit third-party SDKs for new advisories
- Re-test certificate pinning (rotate certs if needed)
- Run a network capture against the app and look for unexpected traffic
- Test on a jailbroken device to confirm graceful behavior
- Re-read App Store Review Guidelines 5.1 (Privacy) for changes
When a security incident happens (and one will): be transparent with users, follow your privacy policy’s disclosure terms, revoke affected credentials immediately, ship a fix fast, document the timeline publicly. Trust is built by handling failures well.