UserDefaults, the old NSUserDefaults, is the easiest place to stash a value on iOS: one line to set, one to read, perfect for a user preference. That convenience is also a trap, because it is easy to reach for it to store a token, a credential, or personal data, and UserDefaults is not secure storage. It is backed by an unencrypted file in your app's container, so anything you put there sits in plaintext, readable on a compromised device and swept into backups. The fix is simple once you know the boundary: preferences go in UserDefaults, secrets go in the Keychain. Here is what UserDefaults is, why it is not secure, and where sensitive data belongs.
Short answer
UserDefaults (NSUserDefaults) is a key-value store for user preferences that is backed by an unencrypted property list file in the app's container, so it is not a secure place for sensitive data. Per OWASP MASVS, secrets and sensitive data should not be stored in plaintext on the device, yet UserDefaults stores its contents unencrypted, where they can be read on a compromised or jailbroken device and are included in device backups. So storing authentication tokens, credentials, or personal data in UserDefaults is an insecure-storage problem. Use UserDefaults only for non-sensitive preferences, and store secrets in the Keychain and other sensitive data in encrypted storage. The boundary is simple: preferences in UserDefaults, secrets in the Keychain.
What you should know
UserDefaultsis for preferences: a simple key-value store.- It is backed by an unencrypted file: a plaintext property list.
- It is not secure storage: contents are readable, not protected.
- It is included in backups: so sensitive data there can leak.
- Secrets belong in the Keychain: not in
UserDefaults.
What is NSUserDefaults, and why is it not secure?
It is a lightweight store for small pieces of user configuration, not a vault. UserDefaults is designed for preferences and settings, a chosen theme, a toggle, a last-used value, accessed by key, and it persists them by writing to a property list file inside your app's container. The crucial fact is that this file is not encrypted: the values are stored in plaintext, so anything written to UserDefaults is readable by anyone who can access the app's container, which includes an attacker on a jailbroken or otherwise compromised device, and analysis of a device or its backup. UserDefaults content is also included in device backups, so it can travel off the device that way. None of this is a flaw in UserDefaults, it is doing exactly what it is meant to, storing preferences conveniently, but it means UserDefaults offers no confidentiality, so it is the wrong place for anything sensitive. The mistake is treating a convenient preferences store as if it were secure storage.
What belongs there, and what does not?
Non-sensitive preferences yes, secrets no. The table draws the line.
Appropriate for UserDefaults | Belongs elsewhere |
|---|---|
| UI preferences and toggles | Authentication tokens and session keys |
| Last-used non-sensitive values | Passwords and credentials |
| Feature flags for the user | Personal or financial data |
| Non-sensitive app settings | Cryptographic keys |
| Onboarding completion state | Anything requiring confidentiality |
The appropriate uses of UserDefaults are small, non-sensitive pieces of state: interface preferences, toggles, feature flags, a remembered non-sensitive selection, onboarding progress, the kind of configuration that does not matter if read. What does not belong there is anything that needs confidentiality: authentication tokens and session identifiers, passwords and credentials, personal or financial data, and cryptographic keys, all of which would be exposed in plaintext if stored in UserDefaults. The simplest way to keep the line clear is to ask whether you would mind the value being read off a compromised device or a backup; if the answer is yes, it does not go in UserDefaults. Secrets like tokens and keys go in the Keychain, which is built to protect them, and other sensitive data goes in encrypted storage.
How do you store data correctly?
Match the storage to the sensitivity of the data. Keep UserDefaults for the non-sensitive preferences it is meant for, where its convenience is exactly right and the lack of encryption does not matter. For secrets, authentication tokens, session keys, passwords, cryptographic keys, use the Keychain, which stores them with protection backed by the device's secure hardware, rather than placing them in a plaintext plist. For other sensitive data that needs to persist, use encrypted storage, encrypting the data with a key kept in the Keychain, so the stored data is not readable in plaintext on the device. Exclude sensitive data from backups where appropriate, and clear sensitive stored values on logout. If you discover sensitive data already in UserDefaults, migrate it to the Keychain or encrypted storage and remove it from defaults. The principle is that storage choice should follow data sensitivity: convenient plaintext storage for what does not need protecting, and the Keychain or encryption for what does, never the reverse.
What to watch out for
The first trap is storing a token, credential, or personal data in UserDefaults because it is convenient, where it sits in plaintext readable on a compromised device and in backups; move secrets to the Keychain. The second is forgetting that UserDefaults content is included in backups, so sensitive data there leaves the device. The third is leaving sensitive values in defaults after logout. A pre-submission scan such as PTKD.com (https://ptkd.com) is well suited to this: it reads the compiled IPA against OWASP MASVS and assesses how your app stores data at rest, surfacing sensitive data kept in insecure locations like UserDefaults, so you can move it to the Keychain or encrypted storage before release.
What to take away
UserDefaults(NSUserDefaults) is a preferences store backed by an unencrypted property list, so it is not secure storage and its contents are readable in plaintext and included in backups.- Storing tokens, credentials, personal data, or cryptographic keys in
UserDefaultsis an insecure-storage problem, since they would be exposed on a compromised device or via backup. - Use
UserDefaultsfor non-sensitive preferences, store secrets in the Keychain, put other sensitive data in encrypted storage, and clear sensitive values on logout. - Use a pre-submission scan such as PTKD.com to surface sensitive data stored in insecure locations like
UserDefaults, then move it to secure storage.

