Overview
Uses Scavio to find public Supabase-powered sites via Google dorks, then probes each app's public tables for disabled RLS. Designed for security researchers and bug bounty hunters tracking the 2026 wave of Supabase RLS leaks. Outputs a CSV of candidates that need disclosure.
Trigger
Cron schedule (daily at 3 AM UTC)
Schedule
Daily at 3 AM UTC
Workflow Steps
Dork for Supabase apps
Scavio Google search for site:*.supabase.co and supabase-js fingerprints in SERP.
Extract project URLs
Parse Supabase project domains and anon keys from the discovered pages.
Probe public tables
Attempt read on common table names (users, profiles, orders) with anon key.
Flag open tables
Any 200 response on a non-RLS-protected table gets flagged as a candidate leak.
Filter duplicates
Dedupe against a history table so previously-reported projects are skipped.
Notify researcher
Push CSV to S3 and post a summary count to Discord for manual review.
Python Implementation
import os, requests, re
API_KEY = os.environ["SCAVIO_API_KEY"]
H = {"x-api-key": API_KEY}
def find_supabase_apps():
r = requests.post("https://api.scavio.dev/api/v1/search",
headers=H, json={"query": 'inurl:supabase.co "anon public"'}).json()
urls = []
for res in r.get("organic_results", []):
m = re.search(r"https://([a-z0-9]+)\.supabase\.co", res.get("snippet", ""))
if m: urls.append(m.group(0))
return urls
def probe(project_url, anon_key):
r = requests.get(f"{project_url}/rest/v1/users?select=*&limit=1",
headers={"apikey": anon_key}, timeout=10)
return r.status_code == 200 and r.json()
for url in find_supabase_apps():
print(url)JavaScript Implementation
const API_KEY = process.env.SCAVIO_API_KEY;
const H = { "x-api-key": API_KEY, "content-type": "application/json" };
async function findApps() {
const r = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST", headers: H,
body: JSON.stringify({ query: 'inurl:supabase.co "anon public"' })
}).then(r => r.json());
return (r.organic_results || [])
.map(x => (x.snippet || "").match(/https:\/\/[a-z0-9]+\.supabase\.co/))
.filter(Boolean).map(m => m[0]);
}
async function probe(projectUrl, anonKey) {
const r = await fetch(projectUrl + "/rest/v1/users?select=*&limit=1",
{ headers: { apikey: anonKey } });
return r.ok ? await r.json() : null;
}
console.log(await findApps());Platforms Used
Web search with knowledge graph, PAA, and AI overviews