List Exposed Tables ๐ด CRITICAL: PROGRESSIVE FILE UPDATES REQUIRED You MUST write to context files AS YOU GO , not just at the end. Write to .sb-pentest-context.json IMMEDIATELY after each discovery Log to .sb-pentest-audit.log BEFORE and AFTER each action DO NOT wait until the skill completes to update files If the skill crashes or is interrupted, all prior findings must already be saved This is not optional. Failure to write progressively is a critical error. This skill discovers all database tables exposed through the Supabase PostgREST API. When to Use This Skill To understand the API attack surface Before testing RLS policies To inventory exposed data models As part of a comprehensive security audit Prerequisites Supabase URL extracted (auto-invokes if needed) Anon key extracted (auto-invokes if needed) How It Works Supabase exposes tables via PostgREST at: https://[project-ref].supabase.co/rest/v1/ The skill uses the OpenAPI schema endpoint to enumerate tables: https://[project-ref].supabase.co/rest/v1/?apikey=[anon-key] What Gets Exposed By default, Supabase exposes tables in the public schema. Tables are exposed when: They exist in an exposed schema (default: public ) No explicit REVOKE has been done PostgREST can see them Usage Basic Table List List tables exposed on my Supabase project With Schema Information List all exposed tables with column details Output Format โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ EXPOSED TABLES โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Project: abc123def.supabase.co Schema: public Tables Found: 8 โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Table Inventory โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ 1. users โโโ Columns: id, email, name, avatar_url, created_at โโโ Primary Key: id (uuid) โโโ RLS Status: Unknown (test with supabase-audit-rls) โโโ Risk: โ ๏ธ Contains user PII 2. profiles โโโ Columns: id, user_id, bio, website, social_links โโโ Primary Key: id (uuid) โโโ Foreign Key: user_id โ auth.users โโโ Risk: โ ๏ธ Contains user PII 3. posts โโโ Columns: id, author_id, title, content, published, created_at โโโ Primary Key: id (uuid) โโโ Risk: โน๏ธ Content data 4. comments โโโ Columns: id, post_id, user_id, content, created_at โโโ Primary Key: id (uuid) โโโ Risk: โน๏ธ Content data 5. orders โโโ Columns: id, user_id, total, status, items, created_at โโโ Primary Key: id (uuid) โโโ Risk: ๐ด Contains financial/transaction data 6. products โโโ Columns: id, name, description, price, stock, image_url โโโ Primary Key: id (uuid) โโโ Risk: โน๏ธ Public catalog data 7. settings โโโ Columns: id, key, value, updated_at โโโ Primary Key: id (uuid) โโโ Risk: โ ๏ธ May contain sensitive configuration 8. api_keys โโโ Columns: id, user_id, key_hash, name, last_used โโโ Primary Key: id (uuid) โโโ Risk: ๐ด Contains secrets โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Summary โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Total Tables: 8 High Risk: 2 (orders, api_keys) Medium Risk: 3 (users, profiles, settings) Low Risk: 3 (posts, comments, products) Next Steps: โโโ Run supabase-audit-tables-read to test actual data access โโโ Run supabase-audit-rls to verify RLS policies โโโ Review high-risk tables first โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Risk Classification Tables are classified by likely content: Risk Table Patterns Examples ๐ด High Financial, secrets, auth orders, payments, api_keys, secrets โ ๏ธ Medium User PII, config users, profiles, settings, preferences โน๏ธ Low Public content posts, products, categories, tags Context Output { "tables" : { "count" : 8 , "list" : [ { "name" : "users" , "schema" : "public" , "columns" : [ "id" , "email" , "name" , "avatar_url" , "created_at" ] , "primary_key" : "id" , "risk_level" : "medium" , "risk_reason" : "Contains user PII" } , { "name" : "orders" , "schema" : "public" , "columns" : [ "id" , "user_id" , "total" , "status" , "items" , "created_at" ] , "primary_key" : "id" , "risk_level" : "high" , "risk_reason" : "Contains financial data" } ] , "by_risk" : { "high" : [ "orders" , "api_keys" ] , "medium" : [ "users" , "profiles" , "settings" ] , "low" : [ "posts" , "comments" , "products" ] } } } Hidden Tables Some tables may not appear in the OpenAPI schema: โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ ADDITIONAL DISCOVERY โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Common Tables Not in Schema (testing existence): โโโ _prisma_migrations: โ Not found โโโ schema_migrations: โ Not found โโโ audit_log: โ EXISTS but not in OpenAPI โโโ internal_config: โ Not found Note: 'audit_log' exists but may have restricted access. Test with supabase-audit-tables-read. โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Schema Analysis The skill also checks for non-public schemas: Schema Exposure Check: โโโ public: โ Exposed (8 tables) โโโ auth: โ Not directly exposed (expected) โโโ storage: โ Not directly exposed (expected) โโโ extensions: โ Not exposed (good) โโโ custom_schema: โ ๏ธ Exposed (3 tables) - Review if intentional Common Issues โ Problem: No tables found โ Solution: Check if anon key is valid Verify project URL is correct The API may be disabled in project settings โ Problem: Too many tables listed โ Solution: This may indicate overly permissive schema exposure. Consider: -- Restrict exposed schemas ALTER ROLE anon SET search_path TO public ; โ Problem: Sensitive tables exposed โ Solution: Either remove from public schema or implement strict RLS. Recommendations by Table Type User Tables -- Ensure RLS is enabled ALTER TABLE users ENABLE ROW LEVEL SECURITY ; -- Users can only see their own data CREATE POLICY "Users see own data" ON users FOR SELECT USING ( auth . uid ( ) = id ) ; Order/Payment Tables -- Strict RLS for financial data ALTER TABLE orders ENABLE ROW LEVEL SECURITY ; CREATE POLICY "Users see own orders" ON orders FOR SELECT USING ( auth . uid ( ) = user_id ) ; -- No public access even for admins via API -- Use Edge Functions for admin operations Secret Tables -- Consider not exposing at all REVOKE ALL ON TABLE api_keys FROM anon , authenticated ; -- Or use views that hide sensitive columns CREATE VIEW public . api_keys_safe AS SELECT id , name , last_used FROM api_keys ; MANDATORY: Progressive Context File Updates โ ๏ธ This skill MUST update tracking files PROGRESSIVELY during execution, NOT just at the end. Critical Rule: Write As You Go DO NOT batch all writes at the end. Instead: Before starting any action โ Log the action to .sb-pentest-audit.log After each table discovered โ Immediately update .sb-pentest-context.json After each significant step โ Log completion to .sb-pentest-audit.log This ensures that if the skill is interrupted, crashes, or times out, all findings up to that point are preserved. Required Actions (Progressive) Update .sb-pentest-context.json with results: { "tables" : { "count" : 8 , "list" : [ ... ] , "by_risk" : { "high" : [ ] , "medium" : [ ] , "low" : [ ] } } } Log to .sb-pentest-audit.log : [TIMESTAMP] [supabase-audit-tables-list] [START] Listing exposed tables [TIMESTAMP] [supabase-audit-tables-list] [SUCCESS] Found 8 tables [TIMESTAMP] [supabase-audit-tables-list] [CONTEXT_UPDATED] .sb-pentest-context.json updated If files don't exist , create them before writing. FAILURE TO UPDATE CONTEXT FILES IS NOT ACCEPTABLE. MANDATORY: Evidence Collection ๐ Evidence Directory: .sb-pentest-evidence/03-api-audit/tables/ Evidence Files to Create File Content tables-list.json Complete list of exposed tables tables-metadata.json Column details and types per table openapi-schema.json Raw OpenAPI/PostgREST schema Evidence Format { "evidence_id" : "API-TBL-001" , "timestamp" : "2025-01-31T10:15:00Z" , "category" : "api-audit" , "type" : "table_enumeration" , "request" : { "method" : "GET" , "url" : "https://abc123def.supabase.co/rest/v1/" , "headers" : { "apikey" : "[REDACTED]" } , "curl_command" : "curl -s 'https://abc123def.supabase.co/rest/v1/' -H 'apikey: $ANON_KEY'" } , "tables_found" : [ { "name" : "users" , "schema" : "public" , "columns" : [ "id" , "email" , "name" , "created_at" ] , "primary_key" : "id" , "risk_level" : "high" , "risk_reason" : "Contains PII" } , { "name" : "orders" , "schema" : "public" , "columns" : [ "id" , "user_id" , "total" , "status" ] , "primary_key" : "id" , "risk_level" : "high" , "risk_reason" : "Financial data" } ] , "summary" : { "total_tables" : 8 , "high_risk" : 2 , "medium_risk" : 3 , "low_risk" : 3 } } Add to curl-commands.sh
=== TABLE ENUMERATION ===
List all exposed tables via OpenAPI schema
curl -s " $SUPABASE_URL /rest/v1/" -H "apikey: $ANON_KEY "