I an building my first iOS application and I need to store the user registration details of the user using the application. The details include his mobile number and a unique id( uuid ) which I use to contact with the backend. It would be great if I could get a suggestion on where to store this user details.
Should I be storing this in the NSUserDefaults or should I be using Keychains to store this data or even may be a using a user model in the database ( I would need a database in any case to store a few other details ). Just to add on, I also would like to perform a few validations like if the mobile number is of proper format and so on before I could actually save it. Also can any one please suggest on the security aspects of different storage mechanisms possible here?
Any help on this would be much appreciated.
The most secure way would be to use keychain services as the data is encrypted but in your scenario it seems a bit over kill. I would recommend either just using NSUserDefaults or an sqlite database I wouldn't really recommend storing in a plist as this can be accessed really easily.
But this all depends on the data you are getting, if it was just uuid and mobile number then NSUserDefaults would do probably, whereas if you were getting usernames and passwords and other personal data I would looking a mix of keychain and sqlite database.
Also you could use coredata file to store user data but seems a bit over kill as well for for such little data.
Just a little note you are actually not allowed to get the iPhones mobile phone number programmatically, getting this would use Private APIs that Apple would reject your app for using.
2.5 Apps that use non-public APIs will be rejected
So you would have to ask he user for this.
Database selection is totally depend on the architecture and security, if you just need to store the few information like login details and some field then Keychain for login details and plist for data is best option, but if your application also working with services and fetching and saving lots of data and continuously updating it then a serious database structure required. In that scenario core data and sqlite both are good option depends on your preference
Following ways you can save details.
In NSUserDefaults
In coredata file.
In sqlite database
Plist file.(Not recommended)
You can save data at server site using webservice.
Any one of these you can use according to your requirement and data.
Cheers :)
If you store information on the UserDefaults, a jailbroken device can see the information you have stored, it is a plist after all. If you are going to keep sensitive data on your device, user defaults itself is not a good option. Possible alternatives:
Use keychain: Keychain is a tool to keep usernames & passwords securely on a device; so you may need to find a way to convert all the info you have mentioned ( a dict, I presume? ) into NSData and put into/get from the keychain but it's been explained on other threads. Additionally, keep in mind that when the app is deleted, keychain data will persist on the device.
UserDefaults & encrpytion: If you can encrypt the data yourself, than using UserDefaults might be a better option. Its more straightforward than keychain and it will be deleted if you delete the app from the device (which may be the thing you want, or not. It depends)
Related
I have an application that is implementing storage using Key/Value pairs in iCloud. From what I read in the documentation this is almost identical to the way NSUserDefaults work.
However this potentially creates a problem because the user should not have the ability to tamper with the app data stored in there. Does this mean that the user can access this data and modify it? Or is it private to the application?
Okay reading deeply in the documentation it says
If your app needs to store passwords, do not use iCloud storage APIs
for that. The correct API for storing and managing passwords is
Keychain Services, as described in Keychain Services Reference.
I found this text here just one line before the last table :)
I also found somewhere that the user can delete his iCloud data manually which can be counted as a modification.
Also, read here, section fro "Start Fresh If Your iCloud Data Becomes Inconsistent During Development" where it says how you can clean the container. Maybe you can check what is visible inside.
It depends what type of data you are storing in the iCloud if it's sensitive then I would use keychain services approach and avoid storing sensitive information on the iCloud.
From the question it seems like you are storing the data in key-value pairs, usually, it's recommended to store preferences, settings, and simple app state and that should be ok because the user can change those, you should choose the right iCloud API for what you want to store
With iCloud the user can always delete the information it has stored as mentioned in the documentation
There may be times when a user wants to delete content from iCloud.
Provide UI to help your users understand that deleting a document from
iCloud removes it from the user’s iCloud account and from all of their
iCloud-enabled devices. Provide users with the opportunity to confirm
or cancel deletion
When you ask
Or is it private to the application?
There's an iCloud identifier in your entitlements file. If it's the same in both apps you'll be able to access the same data/documents across both the apps.
Hope that helps.
I'm new to Swift & Firebase and I haven't really figured it out yet. Currently I'm thinking about adding a Database to store data for the user to fetch in case he switches device.
So far I've stored data with UserDefaults. Now that I'll probably be using a Database, do I still need UserDefaults? What if the user is not able to get internet connection and closes the app, before he gets to synchronize his data going online - will there be a danger of data loss?
Or is it best to keep both - UserDefaults and the Database?
A UserDefaults from Apple documentation:
An interface to the user’s defaults database, where you store key-value pairs persistently across launches of your app. https://developer.apple.com/documentation/foundation/userdefaults
UserDefaults is a great solution for keeping unique values between app sessions. For example user settings, preferences (Simple, dummy data).
To share data between 2 devices you can use Firebase Storage. Another option is a CloudKit.
Synchronisation - this is more about what you need and how you would like to handle it. You can base on online data, so there would not be need to synchronise (you are always up to date). Or make periodically synchronisation, but you would need to think about best solution for local database.
It depends on what you are doing. Using user defaults is certainly fine for holding defaults but not information. What if 2 people use the same device, then you have user defaults for one user and a database for the other. I personally would use just one. If you are learning Firebase I would suggest 2 tutorials:
https://www.youtube.com/watch?v=F42CzqIBxHQ&t=406s
https://www.youtube.com/watch?v=RMudKhNY0sI&t=627s
and the question I just had answered about reading and writing to a secure database: User already authenticated in app and Firebase realtime database returns failed: permission_denied
I'm making an app in which I need to save an array of type [Card], where card is the struct:
struct Card : {
var image : UIImage? = nil
var name : String = ""
var titles : [String] = []
var data : [String] = []
}
What is the best way to persist this array considering that it contains data such as credit card numbers?
Would it be enough to enable Data Protection under the Capabilities tab in XCode? At the moment I'm saving using Codable.
There is no right answer to this, but it's a great way to see how much a person has dug into iOS security. If you're interviewing with a bank I'd almost definitely expect someone to know something about it, but all companies need to take security seriously, so here's the ideal list of topics I'd expect to hear in an answer:
If the data is extremely sensitive then it should never be stored offline on the device because all devices are crackable.
The keychain is one option for storing data securely. However it's encryption is based on the pin code of the device. User's are not forced to set a pin, so in some situations the data may not even be encrypted. In addition the users pin code may be easily hacked.
A better solution is to use something like SQLCipher which is a fully encrypted SQLite database. The encryption key can be enforced by the application and separate from the user's pin code.
Other security best practices are:
Only communicate with remote servers over SSL/HTTPS.
If possible implement certificate pinning in the application to prevent man-in-the-middle attacks on public WiFi.
Clear sensitive data out of memory by overwriting it.
Ensure all validation of data being submitted is also run on the server side.
Sensitive data is not necessarily more secure in the cloud than on a device. Devices can be lost but most data breaches occur with data stored in the cloud. A large database of credit card numbers is a much more attractive target than a single persons credit card information stored on a device. Also, it is quite difficult to recover data from a properly secured iOS device (according to the FBI at least).
That said, any iOS app storing sensitive information should have it's own layer of security above that offered by the device including it's own user authentication process.
Disregarding the numerous reasons not to do this, a good way to securely store local data on iOS is trough the Keychain. It's encrypted with your passcode by the device, is preserved for your app even if it is un-installed, and syncs between devices. The API is kind of hard to understand for beginners, so a wrapper such as https://github.com/kishikawakatsumi/KeychainAccess is a good tool to get started.
In Order to save our apps sensitive data, we should use Security services provided by Apple.
Keychain Services API helps you solve these problems by giving your app a way to store the small amount of user data in an encrypted database called the keychain.
In the keychain, you are free to save passwords and other secrets that the user explicitly cares about, such as credit card information or even short sensitive notes.
You can refer this link for a detailed description of using Keychain Services API.
I'm building an iOS app version of a web app and I need to store the session ID that is returned after a user logs in. All other information that I need is not sensitive, so I'm going to store it in NSUserDefaults, but the session ID is the one sensitive piece of information I can't store in NSUserDefaults. What's the best way to store the session ID?
Why, in the iOS Keychain of course!
iOS Keychain Services
There are many libraries that help with this task, one of the most commonly used is SSKeychain. Although, you could also read the documentation and figure out how to do it yourself, or reference Apple's examples as a way of doing this.
links valid as of June 3rd, 2015
It is pretty secure to store session ID in NSUserDefaults. No other apps can access that.
Although this information can be obtained if you connect the device.
For a more secure way you can always use the built-in keychain access to store the sensitive data
You can store the session id in NSUserDefaults, it's OK because it is visible to the user as a cookie as well. You can also just store the session cookie as a cookie. If you really want to store it safely you can use the keychain.
I am making a app where I need to store some login details.
I searched over internet and found usage of NSUserDefaults has some security issue.
As for keychain, how much data can I store for a single app?
The other option using sqlite also has some security issue.
About application update, how can I preserve data in the next application update.
So which one should I go for?
NSUserDefaults is a big NO for storing any secure data.
If it is only pertaining to user's username & password,i.e sensitive information, then Keychain is the best thing to use.
For other kinds of data(not sensitive) you can use Core Data to store information.
When an update takes place, you can explicitly copy data that is present & import it to your update.
Keychain data as such remains available to the app, after an update.