How secure is NSUserDefaults on iOS 8,9?

15,254

It's highly recommended to not save sensitive data in UserDefaults such as in-app purchases or obviously data such as passwords. Even data like high scores are better saved in keychain so people cannot cheat.

I think that part of the Apple documentation is outdated and should be changed as UserDefaults are not the way to store sensitive data, which in app purchases definitely are IMO.

Just save basic data in UserDefaults like language settings, audio settings etc.

If you want to save sensitive data you should use Keychain. I think the keychain API is quite tricky to use but there is a great helper on GitHub you can use, it has CocoaPods and SwiftPackageManager support and is actively maintained by its author.

https://github.com/kishikawakatsumi/KeychainAccess

There is 2 more projects I used to use which unfortunately no longer seem to be supported

https://github.com/jrendel/SwiftKeychainWrapper

https://github.com/matthewpalmer/Locksmith

One thing to bear in mind with keychain is that data persists even if you delete your app, which I actually consider a good thing.

All credit goes to the authors of their respective wrappers.

Hope this helps

Share:
15,254

Related videos on Youtube

Rasto
Author by

Rasto

Entrepreneur, UX consultant, full-stack developer with strongest competency in Swift & iOS. Can get die-hard about top-notch UX and code quality. Diving deeper into React and getting excited about GraphQL. My pro history chapters are written in C#, Objective-C, Java, JS, TS, Flow, even Haskel, Prolog & Pascal. Sports and outdoor enthusiast. Love exploring cultures around the world. Found in mountains in the winter and at seaside during summer. Amater photographer. Always happy to learn and share what I learned e.g. externally giving lectures at my alma mater.

Updated on July 09, 2022

Comments

  • Rasto
    Rasto almost 2 years

    In-App Purchase Programming Guide suggests you can persist In-App purchase in NSUserDefaults here. However I found this article saying that it is insecure and data in it are easily accessed and modified:

    NSUserDefaults are stored in plist in binary format, with no encryption, and is stored in your app’s directory. This means that any user, even the “noobiest” one, can tinker with your NSUserDefaults with 5 minutes of their time.

    If it is true user can easily get for free anything provided as in-app purchase that is persisted using NSUserDefaults.

    Is the article still correct for iOS 8,9? If so how do you persist your in-app purchases? I prefer some simple solution. I do not (nor want to) validate receipts etc.

    • Sulthan
      Sulthan about 8 years
      User defaults are not secure at all. However, are you really saving sensitive data there?
    • Rasto
      Rasto about 8 years
      @Sulthan Read the question. I want to store In-App purchases there (as Apple recommends). I believe In-App purchases are sensitive enought.
    • Sulthan
      Sulthan about 8 years
      There are many models how you can save paid content in user defaults. If you don't want to validate, you can always use keychain. There are many libraries that allow simple use of keychain, e.g. Locksmith. And keychain is very safe. It also persists if you delete the app and can be shared across devices or apps.
    • Sulthan
      Sulthan about 8 years
      By the way, the most dangerous thing you can do is to use a github library (e.g. IAPManager). There are tools for jailbroken devices that specifically target those libraries by pretending all products were bought.
    • Rasto
      Rasto about 8 years
      @Sulthan Please feel free to have a look on my comment under crashoverride777's answer. I would also like to know your opinion about the matter.
  • Rasto
    Rasto about 8 years
    Thank you. In terms of development time/complexity, can you compare using keychain to receip persisting/validation? I do not have CocoaPods installed (never needed 3rd party library so far) so installing some wrapper might be time comsuming task (perhaps better to use keychain directly?)
  • crashoverride777
    crashoverride777 about 8 years
    I dont understand the Keychain API at all and I am also struggling with receipt validation for months. In terms of difficulty I think keychain is much harder. I also dont use CocoaPods or 3rd party libs, so if you use the 1 wrapper I use (KeychainWrapper JRendel) than you can just copy the swift file into your project.
  • crashoverride777
    crashoverride777 about 8 years
    One thing to bear in mind with keychain is that data persists even if you delete your app, which I actually consider a good thing.
  • Sulthan
    Sulthan about 8 years
    @drasto Cocoapods brought many problems in their day but they are pretty good right now. There are many libraries that will simplify your code a lot or save you development time. The biggest problem is that keychain is a low level C library and interaction with Swift is not trivial (even with Obj-C it was not exactly easy) but it's not too difficult either. If you want to practice Swift, it's a good exercise.
  • crashoverride777
    crashoverride777 about 8 years
    Yeah I am not dissing CocoaPods, I think its great, especially the automatic updates. I still dont really understand it tho and prefer to manually have a hardcoded version in my project for now. As far as I understand the OP wants that too. I still think Keychain API is hard, even tho I have been using this helper for ages and reading a lot about it. I also only learned swift so the easier the better
  • Rasto
    Rasto about 8 years
    The first library would be my pick as it is easier to "install". So the only think to do would be to copy KeychainWrapper.swift (and legal notice) to my project right? Side question: how reliable is that wrapper? My project is before days production - introducing critical code that is not of my own making is huge risk now...
  • crashoverride777
    crashoverride777 about 8 years
    Yeah you just copy the helper as it is from gitHub, it has the legal notice at the top already. It is very reliable, I have been using it in my game for a few months. When you save with the helper returns a boolean value, which is nice. So what I do incase the save method fails and the bool there returns fails I save it in NSUserDefaults, and next time a keychain save is successful I remove the NSUserDefault data. This way you know nothing can happen
  • Ian Warburton
    Ian Warburton over 7 years
    @crashoverride777 Does key chain need to be set up on the user's device before you can use it via these libraries?
  • crashoverride777
    crashoverride777 over 7 years
    No it doesnt need to be turned on. You can use it like UserDefaults and it will just work