What Is This Vulnerability
Hardcoded API Keys in APK is a vulnerability where sensitive API keys, tokens, or secrets are embedded directly in Android application packages. When an APK is decompiled using tools like jadx, apktool, or dex2jar, these secrets are trivially extractable from string constants, resource files, BuildConfig classes, AndroidManifest.xml, or shared preferences defaults.
Mobile developers often hardcode keys during development or embed them in build configurations, assuming the compiled binary provides sufficient obfuscation. In reality, APK decompilation is straightforward and widely practiced.
Why It's Dangerous
Extracted API keys from APKs can be used to:
- Access backend services — Supabase, Firebase, AWS, and other cloud service keys grant direct API access.
- Impersonate the application — attackers can make API calls that appear to come from the legitimate app.
- Access paid services — LLM API keys (OpenAI, Anthropic), mapping services, and other metered APIs result in financial loss.
- Bypass authentication — service role keys or admin tokens enable privileged operations.
- Pivot to other systems — keys for third-party integrations (Stripe, Twilio, SendGrid) expose additional attack surfaces.
Once a key is extracted from a published APK, it must be considered compromised and rotated immediately.
How to Detect
Decompile the APK and search for key patterns:
# Decompile with jadx
jadx -d output/ app.apk
# Search for common API key patterns
grep -r "AIza" output/ # Firebase/Google API keys
grep -r "sk_live" output/ # Stripe secret keys
grep -r "eyJhbGciOi" output/ # JWT tokens (base64 header)
grep -r "supabase" output/ # Supabase URLs and keys
grep -r "sk-[a-zA-Z0-9]\{20,\}" output/ # OpenAI API keys
grep -r "AKIA" output/ # AWS access keys
# Check BuildConfig and resources
cat output/resources/res/values/strings.xml | grep -i "key\|secret\|token"
AuditYour.app's APK scanner automates this process by decompiling the APK, scanning all classes and resources, and matching against a comprehensive set of secret patterns including Supabase, Firebase, Stripe, and LLM provider keys.
How to Fix
Never hardcode secrets in mobile applications. Use these approaches instead:
// BAD: Hardcoded key in source code
val supabaseKey = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
// GOOD: Fetch configuration from a secure backend
suspend fun getConfig(): AppConfig {
val response = httpClient.get("https://api.myapp.com/config") {
header("Authorization", "Bearer ${getAuthToken()}")
}
return response.body()
}
For keys that must be in the app (e.g., Firebase config or Supabase anon key), ensure they are non-privileged and that backend security rules provide the actual protection:
- Use Android Keystore for any secrets that must persist on device.
- Implement certificate pinning to prevent MITM interception.
- Use Firebase App Check or Supabase's JWT verification to validate legitimate app instances.
- Store sensitive keys server-side and proxy API calls through your backend.
- Run ProGuard/R8 obfuscation as a defense-in-depth measure (not a primary control).
Scan your app for this vulnerability
AuditYourApp automatically detects security misconfigurations in Supabase and Firebase projects. Get actionable remediation in minutes.
Run Free ScanRelated
vulnerabilities
Hardcoded API Keys in IPA
API keys and secrets found in iOS application bundles through static analysis of IPA files.
vulnerabilities
Mobile App Credential Extraction
Multiple credentials and secrets extractable from a mobile application through static and dynamic analysis.
vulnerabilities
Exposed Supabase URL in Mobile App
Supabase project URL found in a mobile app binary, enabling targeted attacks against the backend.