VNX-SEC-005 – GCP API Key
Overview
This rule detects GCP API keys matching the AIza[0-9A-Za-z\-_]{35} pattern in source files. GCP API keys are simple credentials used to call Google APIs such as Maps, Places, YouTube, Vision, and Translation. Unlike service account keys, they do not authenticate as a specific identity, but they do authorize API calls that may incur costs or expose data. An unrestricted GCP API key found in a public repository can lead to significant billing fraud and data exfiltration.
Severity: Critical | CWE: CWE-798 – Use of Hard-coded Credentials
Why This Matters
GCP API keys have been abused extensively to run up fraudulent bills against the key owner’s account. There are documented cases of developers committing Google Maps API keys to public GitHub repositories only to find tens of thousands of dollars in unexpected charges days later as bots discovered and exploited the keys for geocoding, translation, or other paid API calls. Some GCP APIs also expose sensitive data — a leaked Vision API key can be used to analyze images at your expense, or a Firebase key may expose real-time database access.
Because GCP API keys do not expire and are not tied to a user identity, detecting their unauthorized use requires careful review of GCP Console logs. The key remains usable until it is explicitly deleted or restricted.
What Gets Flagged
A standalone 39-character token, AIza followed by 35 URL-safe base64 characters, in any file: script URLs (?key=AIza...), Android string resources, Firebase web configuration, Java constants, request parameters and .env files.
<!-- FLAGGED: key in an Android string resource -->
<string name="google_maps_key">AIza<35 characters></string>
// FLAGGED: Firebase web config
const firebaseConfig = { apiKey: "AIza<35 characters>", projectId: "shop-prod" };
Firebase web keys are designed to ship to browsers, but an unrestricted key still bills the project, so they are reported; restrict the key by API and HTTP referrer.
Not flagged:
- Placeholder runs (
AIzaXXXXXXXX...) and theAIzaprefix inside a longer token. - Prefix checks (
key.startsWith("AIza")) and environment references. - Test, fixture, vendored and generated files.
Remediation
Restrict or delete the exposed key immediately. In the GCP Console go to APIs & Services → Credentials → find the key → Edit. Either delete it and create a new one, or apply restrictions immediately before creating a replacement.
Apply key restrictions to any new keys. GCP allows you to restrict keys by:
- Application restrictions: Limit to specific HTTP referrers, IP addresses, Android apps, or iOS apps.
- API restrictions: Limit to only the specific APIs the key needs (e.g., Maps JavaScript API only).
# Restrict key to specific IP addresses via gcloud
gcloud services api-keys update KEY_ID \
--allowed-ips=203.0.113.0/24
- Remove from source code. Load the key from environment variables instead:
# SAFE: load from environment variable
import os
import googlemaps
gmaps = googlemaps.Client(key=os.environ['GOOGLE_MAPS_API_KEY'])
- Use Application Default Credentials (ADC) as the proper alternative. For server-side GCP services (Vertex AI, Cloud Storage, BigQuery), ADC authenticates automatically using the service account attached to the compute resource — no API key or credentials file needed:
# SAFE: ADC for GCP server-side APIs — no key required
from google.cloud import storage
client = storage.Client() # Uses ADC automatically
bucket = client.bucket('my-bucket')
Check GCP audit logs for unauthorized API usage. In the Console go to Logging → Log Explorer and filter for the API key ID. Look for calls from unexpected IP addresses or with unusual request volumes.
Scan git history for the exposed key:
gitleaks detect --source . --verbose
git filter-repo --replace-text <(echo 'AIzaSyDxxx==>REDACTED_GCP_KEY')