Security

    Why NSUserDefaults is not secure storage

    A 2026 view contrasting non-sensitive preferences in UserDefaults with secrets stored in the Keychain, since the UserDefaults plist is unencrypted and included in backups

    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

    • UserDefaults is 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 UserDefaultsBelongs elsewhere
    UI preferences and togglesAuthentication tokens and session keys
    Last-used non-sensitive valuesPasswords and credentials
    Feature flags for the userPersonal or financial data
    Non-sensitive app settingsCryptographic keys
    Onboarding completion stateAnything 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 UserDefaults is an insecure-storage problem, since they would be exposed on a compromised device or via backup.
    • Use UserDefaults for 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.
    • #ios
    • #nsuserdefaults
    • #userdefaults
    • #insecure-storage
    • #keychain
    • #owasp-masvs
    • #app-security

    Frequently asked questions

    Is NSUserDefaults secure?
    No. UserDefaults is designed for preferences and persists them by writing to a property list file inside your app's container, and that file is not encrypted, so the values are stored in plaintext. Anything written to UserDefaults is readable by anyone who can access the app's container, including an attacker on a jailbroken or compromised device, and through analysis of a device or its backup. This is not a flaw, it is doing what it is meant to, but it means UserDefaults offers no confidentiality, so it is the wrong place for anything sensitive.
    What can I safely store in UserDefaults?
    Small, non-sensitive pieces of state: interface preferences and toggles, feature flags, a remembered non-sensitive selection, onboarding progress, and similar configuration that does not matter if read. The simplest test is to ask whether you would mind the value being read off a compromised device or a backup; if you would not mind, it is fine for UserDefaults. If you would mind, it does not belong there. UserDefaults is the right tool for convenient preference storage, just not for anything that needs to be kept confidential.
    Where should I store tokens and credentials instead?
    In the Keychain. The Keychain is built to store secrets like authentication tokens, session keys, passwords, and cryptographic keys with protection backed by the device's secure hardware, rather than as plaintext in a 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. Match the storage to the data: convenient plaintext UserDefaults for non-sensitive preferences, and the Keychain or encryption for anything requiring confidentiality.
    Does UserDefaults data end up in backups?
    Yes. UserDefaults content is included in device backups, so sensitive data stored there can travel off the device through a backup even if the device itself is not directly compromised. That is an additional reason not to store secrets or personal data in UserDefaults. Keep secrets in the Keychain, which is handled appropriately, put other sensitive data in encrypted storage and exclude it from backups where appropriate, and clear sensitive stored values on logout so there is less exposed both on the device and in any backup.
    How do I find sensitive data stored insecurely?
    Scan the build. A pre-submission scan such as PTKD.com 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 act on it. If it shows tokens, credentials, or personal data in UserDefaults, the fix is to migrate those to the Keychain or encrypted storage and remove them from defaults. This kind of insecure-storage issue is exactly what a static look at the build can flag before release.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free