Open martinbonnin opened 3 years ago
Hi @martinbonnin, thanks for the feedback and questions. The underlying idea behind the plugin is that your keys should be kept a secret as much as possible and not be easily visible in your source code, which is perhaps the easiest way to find keys. As you pointed out, while this plugin does keep keys out of version control, keys are still recoverable by decompiling an APK. So, securing your key using other measures is still necessary. For example, with a Google Maps Platform API key you can add application restrictions so the key can only be used within the context of your app. I will add as a disclaimer to the README about this.
As far as use cases go, I think you've captured it. This plugin came to be out of necessity while developing Android samples for the Maps SDK and Places SDK wherein developers downloading the sample app need to insert their own API key (which falls under the 1st use case you mentioned). In my opinion, even for private Git repos, API keys should still be hidden from Git history, but that's perhaps more of a philosophical opinion. For the sake of drawing an analogy, if your API key is the key to your front door, even though most locks can be picked, you still won't leave your keys out in the open.
Thanks for the explanations 🙏
@arriolac I had the same question as @martinbonnin and I am glad that you've answered it here. I'd like to contribute here with a nuanced and pragmatic insight into risks of secret management on Android and to hopefully direct the future discussion away from philosophical debates.
In the end of the day all security measures are a trade-off between convenience and safety, this is the main reason why a security expert is still a job and is not a checklist of TODOs that all and every project needs to go through. Google with thousands of engineers and a monorepo might be afraid of keeping secrets on Git. Non-FAANG companies with a 1000 customers, 10 engineers and 5 repos though?
For the vast majority of closed source projects out there - the risk of storing a key in a private repo is not considered worth addressing outside of securing the aforementioned repo with 2FA. For Android projects where reverse engineering of a binary is as easy as opening a .RAR file it is considered to be pretty much a futile effort. Even the opposite - the risk of losing the keys forever because they were never committed to the repo is considered to be higher.
Case in point
If you ever lose your Google Play signing key - you lose your whole app, with all it's current install base FOREVER. For any business it's considered to be a catastrophic loss. It is such a big problem that even Google is now offering a workaround that basically stores your company's secrets on Google's remote server indefinitely - Play App Signing. It does not really sound all that different from uploading your keystore to a repo to me.
On the other hand - if someone gets your API secret from your repo or APK - no big deal, in client-server architecture you are not ever supposed to trust the client and in worst case scenario - you should be able to routinely rotate any compromised API key or blacklist the existing ones. In many companies API keys are changed every new version of the app.
If Google is interested in further supporting security of their platform - I'd suggest them to look into creating a first party secret management API that would bake-in secrets into the binary with different salts every build.
Hi @martinbonnin, thanks for the feedback and questions. The underlying idea behind the plugin is that your keys should be kept a secret as much as possible and not be easily visible in your source code, which is perhaps the easiest way to find keys. As you pointed out, while this plugin does keep keys out of version control, keys are still recoverable by decompiling an APK. So, securing your key using other measures is still necessary. For example, with a Google Maps Platform API key you can add application restrictions so the key can only be used within the context of your app. I will add as a disclaimer to the README about this.
As far as use cases go, I think you've captured it. This plugin came to be out of necessity while developing Android samples for the Maps SDK and Places SDK wherein developers downloading the sample app need to insert their own API key (which falls under the 1st use case you mentioned). In my opinion, even for private Git repos, API keys should still be hidden from Git history, but that's perhaps more of a philosophical opinion. For the sake of drawing an analogy, if your API key is the key to your front door, even though most locks can be picked, you still won't leave your keys out in the open.
How can decompiling the APK help you discover the API keys if the properties file is not compiled into the APK via gitignore? Are you implying the values can be extracted from the variables that call them by recoding a cloned version? Is it really so simple to get the API key values from code using this library?
if the properties file is not compiled into the APK via gitignore
Compilation has nothing to do with gitignore. Gitignore is about not pushing your file to GitHub (or any other host). Your file will still be compiled into the APK or app bundle you upload to the Google play.
Hi 👋 ! Thanks for the plugin! I am not 100% sure when it should be used though.
Secrets like apiKeys are typically super hard (if not impossible) to secure in an app that is shipped to thousands of people. Someone could disassemble the apk and get the apiKeys from the bytecode.
Not having the secrets in source control is nice but ultimately, devs will need an apiKey to work, which means the secrets will be stored on their machine. And the CI would need it as well, which means most of the places where the repository will be cloned will most likely contain the secret.
The use cases I can think of are:
Are there other use cases?
In all cases, I think a disclaimer about the apiKeys being easily extractable from the final app would be nice.