Keeping Secrets in iOS app.
Using keys (may it be third-party initializer keys, API keys or your cryptographic secret keys) is usually inevitable when it comes to developing an app which performs more than just greeting Hello to the entire World 😁And obviously, we’d never love, even the thought of secrets (in our app) to be disclosed (just like in our real lives).
Imagine your Google Maps Key get leaked and now someone else is misusing your paid Google services for free, while you’re being overcharged for your actual usage — A nightmare!
You might be wondering, are our keys on client-side really vulnerable to attacks/leakage? Assuming they are not being transmitted over the internet and just being used locally in the code. The answer is YES, because:
1. Hard coded keys in the source code can be obtained by decompiling the app files.
2. Hard coded keys in the source control can also be revealed, if the source control gets compromised.
Therefore, its really necessary to take measures to keep our keys secure, as much as possible, and here’s a way on how to do it
So how to store our secrets on the client-side?
We are going to discuss the easiest, yet quite effective Apple’s way, by using Xcode Configurations and Info.plist.
Step 1:
Create a New Project in Xcode.
Step 2:
Add a New Config File in the Project
Step 3:
Make sure you don’t check any Targets which is also the default in Xcode
Step 4:
Now add a key you want to hide, e.g. any API Key in the Config.xcconfig file
Step 5:
Now add the Secret Key to your info.plist. The SECRET_KEY in our Config.xcconfig acts as a variable which can be accessed by $(SECRET_KEY) on the info.plist.
Step 6:
Now set the Config.xcconfig to the Configurations to our App Project.
You can always create different xcconfigs for Debug & Release, for simplicity of this article we will keep one for both environments.
Step 7:
Now let’s do a simple check if we can access our Secret Key in the code.
Now let’s build & run, and the console should print our Secret Key (that we set in Config.xcconfig) successfully.
Success! Your keys are in safe hands now :)
But how exactly can a hardcoded key be hacked?
Let’s add a hardcoded Key (MyKey In my case) just to see how it can be hacked but the Secret Key from xcconfig might not.
Now create an Archive. Find the Archive by Show in Finder from Organiser. Go to App Executable folder by Show Package Contents on the Archive -> Products -> Applications. Find the App Binary by Show Package Contents on App Executable. It will look something like this:
cd to this folder in Terminal & run strings command on the App Binary. You can find HARDCODED MyKey, but not SECRET_KEY from xcconfig.
But where is our Secret Key exactly?
Now the question might arise, where is our SECRET_KEY from the xcconfig? It’s residing in the info.plist in our App Executable.
If you open it, you can find the SECRET_KEY with its value exposed.
Now, someone may argue that it’s easily hackable, could also be easier than our HARDCODED MyKey. But, generally if someone has an access to your Archive, then he’s an inside guy who already knows the value.
Now, let’s assume a hacker. He can hack into our repo or the App Binary. In either case, he won’t get to understand about our Config.xcconfig from the repo or the SECRET_KEY from the App Binary.
As a better practice, try to avoid using Secret Keys whenever you can. If not, try adding some measures to hide them from attackers, like the one we just learned.
Use Secure Network Connections like Transport Layer Security (TSL) by using Apple’s Network Framework or App Transport Security of URLSession as explained in the WWDC Video 2019 (13:00).
Use SSL Certificate Pinning to stay safe from Bots, Proxies, or Man-in-the-Middle Attacks.
Happy Coding & Sharing!