Application Security Musts for every iOS App
Application security is one of the most important aspects of software development.
Users of our apps expect that their pieces of information are being kept private. Our sensitive application data should not be simply given away.
Fortunately, in this article, we will discuss mistakes that developers make towards app security and how to easily fix them.
Storing sensitive data in the wrong places
I have researched multiple apps from the AppStore and a lot of them are doing the same mistake, storing sensitive data where they do not belong.
If you are storing sensitive data in
UserDefaults, then you are risking your application's information.
UserDefaults get stored simply as a property list file that is located inside Preferences folder of your app. They get saved in our app without being encrypted in any form.
Basically, by using a third party mac application like iMazing for the example, without even having to Jailbreak your device, you can easily view
UserDefaults data for any app downloaded from the AppStore.
These mac apps are simply designed to allow you to explore and manage third-party application files that are on your iPhone. And you can easily explore
UserDefaults of any app.
The Reason that pushed me to write this article was that I found out that lots of apps that I had installed from the AppStore write their sensitive data on User Defaults.
Examples are Access Tokens, Active Renewable subscription flags, Number of available coins etc.
All this data can be easily retrieved and altered and make damage to apps, from free usage of paid features to hacking network layer and much more.
The right way to do it
You should always keep in mind one thing when saving data on iOS apps,
UserDefaults is designed only to save a small amount of data like preferences of a user inside the app, stuff that is completely insensitive.
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 also store items like the cryptographic keys and certificates that you manage with Certificate, Key, and Trust Services.
Keychain Services API
Below we are going to describe how you can save password of your user inside of keychain.
The query dictionary part
kSecClass:kSecClassGenericPassword indicates that the item is a password, from which keychain services understands that the data requires encryption.
We then add the new password to the keychain by calling
SecItemAdd with the query we created.
Retrieving the data is similar
We can write a simple test to ensure that data is saved and retrieved correctly
Keychain API can seem a bit complicated to use at first if you have to save more than a single password I encourage you to create a facade for it that helps you to save and modify data in best way depending on your app use cases.
If you want to know more about the facade pattern and how to create simple wrappers for complex subsystems, then this article can help you a lot.
Saving Passwords and performing Authentication
In my career as an iOS developer, I have seen the same mistake keeping repeated over and again.
Lots of times Developers either save raw passwords on the app to reuse them or make login network requests directly with username and password.
If you are storing passwords directly in
UserDefault then you should know by now how much are you risking from the information provided in the first section of this article.
Saving passwords to Keychain takes security to a better level but then again, we should always save passwords and other sensitive information to the keychain or elsewhere by initially encrypting them.
Let’s say that an attacker can hack through keychain security or attack us through our network, from there he can retrieve our passwords directly as raw text.
A better approach is to store passwords and use them for login requests as a hash built for this password.
Encrypting Sensitive Data
Implementing hashing by yourself can be really complicated and overkill, so in this article, we will use the help of an open source iOS Library CryptoSwift.
CryptoSwift is a growing collection of standard and secure cryptographic algorithms implemented in Swift.
Let us try to save and retrieve a password on keychain by using CryptoSwift provided algorithms.
This method takes an account and password and saves a hashed string on Keychain instead of a direct string.
Let us break down what is happening in this method
- The salt is a unique string used to mix the password.
sha256completes type SHA-2 hash
- HKDF is a simple key derivation function (KDF) based on a hash-based message authentication code (HMAC)
We create a salt to make it more challenging for us to get attacked.
If we hashed only our password a hacker might have a list of most used passwords and create their hashes and compare them to our created one. And could easily then find our password for a given account.
Now we can authenticate to the server using our account and our custom key instead of a direct password.
Of course, the app and the server should share the same salt. Backend then would have to compare same keys created by using the same algorithm, to verify the user.
By using this approach we take our security to a next level and make attacking our app a highly complex task.
Implementing security for our apps should be a task that should never be neglected.
Initially, In this article, we have discussed issues that can arise from saving sensitive data to UserDefaults. We discussed why you must save them on the Keychain to avoid attackers to easily view them.
In the second section, we talked more about taking the security to the next level by saving sensitive data by encrypting first and also discussed the right way to communicate with a server when sharing sensitive data in our case user identity.
If you enjoy this article make sure to clap to show your support.
Follow me to view many more articles that can take your iOS Developer skills to a next level.
If you have any questions or comments feel free to leave a note here or email me at email@example.com.