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_log or print (use .private for 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.resolved committed)
  • 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-dependencies and 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 Codable types (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 serverTrust policy)

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.xcprivacy reflects 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 .completeUntilFirstUserAuthentication or .complete protection
  • 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.localOnly if 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 SecRandomCopyBytes or CryptoKit, never arc4random() 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 (SceneDelegate blurs 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:

  1. Re-run this checklist
  2. Audit third-party SDKs for new advisories
  3. Re-test certificate pinning (rotate certs if needed)
  4. Run a network capture against the app and look for unexpected traffic
  5. Test on a jailbroken device to confirm graceful behavior
  6. 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.