Join our Newsletter — 33% off our NHI Course

iOS UserDefaults (Insecure Storage)

iOS UserDefaults is a local key-value storage API for small app preferences and simple state. It is not suitable for secrets, because values can be exposed through device backups, app data extraction, or a compromised device. Store tokens, passwords, and sensitive identifiers in protected storage instead.

Why iOS UserDefaults should never hold secrets

UserDefaults is designed for lightweight app preferences, not for confidentiality. On iOS, anything you place there should be treated as recoverable by someone who can inspect app data, extract a backup, or work from a compromised device, which makes it a poor place for tokens, passwords, session material, or sensitive identifiers.

The security problem is not that UserDefaults is “broken”, but that it solves the wrong problem. It is a convenience store for small, non-sensitive state, so developers sometimes use it for values that feel harmless during development and become exposure points in production. That gap between convenience and sensitivity is where insecure storage starts.

How insecure storage exposure typically happens

Data placed in UserDefaults can become visible through several ordinary device and application pathways. Backups may include the values, app data extraction can reveal them, and a compromised or jailbroken device can expose them alongside other local application files. The risk grows when the stored value can be used to authenticate elsewhere, because disclosure is then immediately operational, not merely informational.

For that reason, the term is best understood as a local data handling weakness with downstream identity impact. If the stored item is a bearer token, API key, refresh token, password, or device-bound identifier, compromise can let an attacker impersonate the app or the user until the secret is revoked or expires.

Safer storage patterns for sensitive app data

Sensitive values belong in protected storage mechanisms, not in a plain preferences API. In iOS practice, that usually means choosing Keychain-backed storage or another platform control that is specifically intended to protect secrets at rest and under device compromise conditions. The key decision is to separate application state from authentication material, rather than trying to “hide” secrets inside a convenience store.

The same rule applies to identifiers that function like secrets, such as long-lived session tokens or locally cached credentials. If a value can be replayed, used to restore access, or exchanged for privileges, it needs the same protection mindset as a password. Storing it in a user preference container weakens that protection from the start.

What a secure review should check

Teams should review whether any value written to UserDefaults can unlock accounts, services, or sessions if read by an attacker. The review should also consider whether the app mirrors those values into logs, analytics, debug output, backups, or other local caches, because insecure storage often appears in more than one place at once.

When a sensitive value has already been stored there, the practical question is not only where it should go next, but whether it should be rotated or invalidated after migration. A leaked credential stored locally may remain useful to an attacker even after the app is updated, so remediation often needs both secure re-storage and exposure response.

Risk and Threat Considerations

Insecure storage becomes dangerous when a local preference value can be read outside the app’s intended trust boundary. The most serious cases involve tokens, keys, passwords, or persistent identifiers that turn local disclosure into account compromise, API abuse, or session hijacking.

Failure mechanism: An attacker extracts the app container, reads UserDefaults content from a backup or compromised device, and reuses any sensitive value that was never meant to be recoverable in cleartext.

Impact: Exposure can lead to unauthorised access, impersonation of the app or user, privilege misuse, and the need to revoke or rotate affected credentials and sessions.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

OWASP ASVS, NIST SP 800-53 Rev 5 and CIS Controls v8 set the technical controls, while ISO/IEC 27001:2022 defines the regulatory obligations.

Framework Control / Reference Relevance
OWASP ASVS V14 — Data Protection UserDefaults insecure storage is a data-protection weakness for sensitive local app data.
V6 — Authentication Secrets in UserDefaults can directly undermine app authentication and session security.
Recommendation — Store secrets in protected storage and verify that sensitive data is never written to low-trust local preferences. Validate that authentication material is never persisted in insecure local storage.
NIST SP 800-53 Rev 5 IA-5 — Authenticator Management The term concerns the storage and lifecycle of passwords, tokens, and other authenticators.
Recommendation — Protect, store, and rotate authenticators in a way that prevents disclosure from local app storage.
CIS Controls v8 CIS-3 — Data Protection Insecure storage of sensitive app data maps to protecting data at rest and reducing exposure paths.
Recommendation — Classify sensitive local data and keep it out of low-protection storage locations.
ISO/IEC 27001:2022 A.8.24 — Use of cryptography Sensitive values need encryption or protected handling rather than plain preference storage.
Recommendation — Apply protected storage or encryption for data that must remain confidential at rest.

Practitioner Guidance

What to watch for: Treat any value that would be harmful if copied off-device as out of bounds for UserDefaults. That includes bearer tokens, passwords, API keys, refresh tokens, and any identifier that behaves like an authentication secret.

Governance implication: Security review should explicitly classify storage locations by sensitivity, so developers do not rely on convenience APIs for material that needs confidentiality. If a value supports login, authorization, or session continuity, it needs a storage choice that matches that role.

Practitioner takeaway: Use UserDefaults for preferences, not protection. If the data matters enough to guard, it belongs in a control designed to keep it secret.