How do we store our secrets on the client-side? Are we really vulnerable to attacks? Is it really worthwhile to take the measures to store them securely?
Almost all the iOS apps have some secret keys to protect like:
- API keys
- Private Headers
- Cryptographic Keys
These keys are needed:
- to set up third-party SDKs
- to authenticate with backend APIs
- to automate build process or to use in any developer tools, such as communicating to Apple Developer Account or App Store Connect
But imagine a situation, where they are compromised, for instance, if someone gets hold of our Firebase API key, now he/she can easily misuse or overuse our paid credentials if he/she is determined & skilled to hack into few other related keys.
Q: Are our keys really this vulnerable to attacks?
A: Yes & No
Yes: If we hardcode them in the source code or if we push them on the source control.
No: If we take some basic measures to secure them, also it takes little determination and a lot of skills from a hacker to extract or debug them from the binary.
Q: Is it really worthwhile to take the measures to store them securely?
A: Yes & No
Yes: Because they are our App Secrets
No: Because we can’t make it 100% hack-free
Be aware you should authenticate users, not authenticate an app. It’s mathematically impossible to hide data perfectly yet still be able to access it from your code.
- Chris Hulbert from Splinter
How do we 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.
Add a New
ConfigFile in the Project
Make sure you don’t check any Targets which is also the default in Xcode.
Let’s add an API Key in the
Add Config.xcconfig to the gitignore. This step is very important as we don’t want it to be available to everyone who has access to our repo.
If due to some reason our repo is compromised, the hacker won’t get hold of our secrets.
Let’s add the API Key to our
info.plist. The API_KEY in our
Config.xcconfig acts as a User-defined Variable which can be accessed by
$(API_KEY) on the
Let’s 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.
Let’s do a simple check if we can access our API Key in the code.
let apiKey = (Bundle.main.infoDictionary?["API_KEY"] as? String)! print(apiKey)
That should do it ✅
If this Article was useful to you, consider donating in crypto:
With love and respect,