How to find hardcoded API keys and secrets in an Android APK
Three ways to find leaked API keys, tokens and credentials inside an Android APK — manual decompilation, string grepping, and automated static analysis with redacted evidence.
Last updated 2026-09-05
classes.dex), resources, bundled assets/, and the manifest. You can extract them by decompiling and grepping for known key patterns — or review static detections in a scan report. A string match does not establish that a credential works.Read in context. These instructions need to be adapted to your app and platform version. New scans provide static detections; they do not establish current backend access. Current methodology.
Why secrets end up in APKs
Anything shipped inside an app is client-side and fully recoverable — there is no "hidden" in a distributed binary. Developers embed API keys, cloud credentials, signing material and backend URLs for convenience, but every one of them travels to the user's device and can be extracted.
Option 1 — decompile and grep (manual)
An APK is a ZIP. Unpack it, convert the DEX to readable form, then search for high-signal patterns:
unzip app.apk -d app/ # tools like apktool or jadx recover resources & smali/Java grep -rE "AKIA|AIza|sk_live_|xox[baprs]-|firebaseio\.com|-----BEGIN" app/
Patterns worth searching for
| Prefix / pattern | What it is |
|---|---|
AKIA… | AWS access key ID |
AIza… | Google API key |
sk_live_… | Stripe live secret key |
xoxb-/xoxp- | Slack token |
-----BEGIN … PRIVATE KEY----- | Private key material |
*.firebaseio.com | Firebase Realtime Database URL |
Option 2 — the problem with grep
String matching is noisy: it flags sample keys, test fixtures and restricted client keys as if they were live secrets, and it tells you nothing about whether a match is exploitable. A Google API key restricted to one app package is low-risk; an unrestricted one is not — grep can't tell them apart.
Option 3 — scan it (and verify)
apk-scanner.com provides static findings, build details and analysis coverage. Scans check whether a referenced backend answers an unauthenticated request, never using a detected credential and never reading stored data. Review the current methodology and each report’s limitations.
Found one? Do this immediately
- Rotate/revoke the key now — assume it is already compromised the moment it shipped.
- Move the secret server-side and have the app call your backend with per-user auth.
- Restrict what you must ship (e.g. lock a client API key to your package + specific APIs).
- Audit access logs for use of the leaked credential while it was exposed.
Frequently asked questions
Can I find secrets without decompiling?
Partly — strings in resources and assets are readable straight from the ZIP, but code-level constants live in the compiled DEX, which needs decompiling (or a scanner) to read reliably.
Are client-side API keys always a vulnerability?
No. Some keys are designed to ship (e.g. a restricted Google Maps key). The risk is an unrestricted or secret key — like a Stripe live key or a cloud service-account credential — that grants real access.
How do I know if a leaked key is still active?
A string match does not establish whether a key is active. New scans do not test discovered credentials or contact detected backends. Review your own provider configuration.