1,057 out of 2,500 top and trending apps on Google Play leak at least one secret credential, such as an access token or password, according to Comparitech researchers. These secrets could be used by malicious hackers to attack apps, APIs, and end users.
We often think of “credentials” as the information we need to log into an app or website, such as your email address and password. But credentials also include passwords and tokens used by apps themselves to authenticate various connections to first- and third-party servers, APIs, and other endpoints.
Our researchers found many apps hard code credentials and webhooks in plain text, which can be easily accessed by users and other applications. Comparitech researchers used two open-source tools, APKLeaks and Quark Engine, to analyze 2,500 Android top and trending apps on Google Play for leaked secrets.
The credentials leaked by the analyzed apps included:
- Amazon Web Services API keys
- Facebook tokens
- Github tokens
- Google API keys
- Twitter OAuth tokens
- PayPal API keys
- Twilio API keys
- Slack webhooks
- Heroku API keys
- MailChimp keys
- Other generic API keys
- App secrets
- Custom API keys
In addition to the leaked secrets, researchers also found IP addresses pointing to unsecured Firebase servers and AWS buckets.
Flawed credential storage could be exploited by malicious hackers to fraudulently access and abuse app APIs, steal sensitive data, phish users, and spread malware. We’ll highlight some of the more common leaks below.
Application programming interfaces (APIs) are used by a lot, if not most, Android apps. They allow one app to access data or functions of another app without exposing all of the second app’s source code or data. For example, a hotel comparison app uses each hotel’s API to fetch available dates and prices. API access usually requires authentication through a secret API key or token.
Researchers found API credentials are often stored in an unprotected way. One example stored credentials as constants, which would allow any other application to read and act on them.
Researchers were able to manipulate hardcoded API credentials to reverse the way an application sends requests for tokens and retrieves them. In one case, researchers found an API token for a popular US delivery service that allowed them to access a private API endpoint for parcel tracking. The researchers stopped there, saying an attacker could exploit the same vulnerability to steal private customer information. The app leaked five separate secret credentials.
API tokens are increasingly used in credential stuffing attacks. Credential stuffing typically entails a bot using stolen credentials to access other accounts that share the same password, token, or key. API endpoints are frequent targets for credential stuffing attacks, especially in the financial sector.
Webhooks are automated messages sent from apps when triggered, similar to SMS notifications. They can augment the behavior of an app using custom callbacks, which are managed by third-party users and developers who might not be affiliated with the original app’s developer. Webhooks are frequently used in chat apps like Facebook Messenger and Slack, but also to track bugs and automate version control.
Researchers found they could launch attacks against hardcoded webhooks. Slack, the popular workplace chat app, uses a hardcoded webhook for accepting user feedback. Researchers could send a large volume of requests to the hook, overloading the server and causing a denial of service attack.
Researchers say threat actors could use similar requests to drop malware payloads in an attempt to expose a database or upload a malicious script to the application’s server.
The Slack webhook could also be exploited by sending fake feedback from non-existing users to mislead developers. Or attackers could send phishing messages with links to malicious websites.
How to safely store secrets in Android apps
Our researchers gave the following credential storage advice for Android developers:
- Use the Android Keystore API to implement most of the needed credential storage functionality.
- Exclude credentials and webhooks during commits. Add them to .gitignore before any commits. Later, developers just need to add all necessary keys to apikey.properties and read it using appropriate methods in the app itself. Then all secret values will be within the app and you won’t need to check the actual values in your git repository. Note this might not protect secrets during decompilation.
- Obfuscate using ProGuard – ProGuard is a tool that helps obfuscate one’s own application. This doesn’t exclude secrets, but instead makes them more difficult to reveal through decompilation.
- Ensure credentials are unique so they can’t be used in credential stuffing attacks.
- Store secrets in NDK – The Android NDK is a toolset that lets you implement parts of your app in native code. Storing credentials here makes decompilation and reverse engineering more difficult for attackers. When you store credentials in NDK, the credentials are…
- Obfuscated using the XOR operator so they never appear in plain sight. This is not more secure, strictly speaking, but can help prevent credential theft by automated extractors.
- Stored in an NDK binary as a hexadecimal array, making them harder to find.
- Not persistent in binary to force runtime evaluation.
To add an additional security layer, developers can use an encoding algorithm with the NDK plugin.