supabase-audit-tables-list
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseList Exposed Tables
列出暴露的表
🔴 CRITICAL: PROGRESSIVE FILE UPDATES REQUIREDYou MUST write to context files AS YOU GO, not just at the end.
- Write to
IMMEDIATELY after each discovery.sb-pentest-context.json- Log to
BEFORE and AFTER each action.sb-pentest-audit.log- 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.
🔴 重要提示:需要逐步更新文件你必须逐步写入上下文文件,而不是仅在最后统一写入。
- 每次发现后立即写入
.sb-pentest-context.json- 每次操作前后都要记录到
.sb-pentest-audit.log- 不要等到技能完成后再更新文件
- 如果技能崩溃或被中断,所有之前的发现必须已保存
这不是可选要求。不逐步写入属于严重错误。
本技能可发现通过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
- 了解API攻击面
- 测试RLS策略之前
- 盘点暴露的数据模型
- 作为全面安全审计的一部分
Prerequisites
前提条件
- Supabase URL extracted (auto-invokes if needed)
- Anon key extracted (auto-invokes if needed)
- 已提取Supabase URL(如果需要会自动调用提取)
- 已提取anon key(如果需要会自动调用提取)
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]Supabase通过PostgREST在以下地址暴露表:
https://[project-ref].supabase.co/rest/v1/本技能使用OpenAPI schema端点枚举表:
https://[project-ref].supabase.co/rest/v1/?apikey=[anon-key]What Gets Exposed
哪些内容会被暴露
By default, Supabase exposes tables in the schema. Tables are exposed when:
public- They exist in an exposed schema (default: )
public - No explicit has been done
REVOKE - PostgREST can see them
默认情况下,Supabase会暴露模式下的表。满足以下条件时表会被暴露:
public- 表存在于暴露的模式中(默认:)
public - 未执行过显式的操作
REVOKE - PostgREST可以访问该表
Usage
使用方法
Basic Table List
基础表列表
List tables exposed on my Supabase project列出我的Supabase项目中暴露的表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
══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
暴露的表
═══════════════════════════════════════════════════════════
项目:abc123def.supabase.co
模式:public
发现的表数量:8
─────────────────────────────────────────────────────────
表清单
─────────────────────────────────────────────────────────
1. users
├── 列:id, email, name, avatar_url, created_at
├── 主键:id (uuid)
├── RLS状态:未知(使用supabase-audit-rls测试)
└── 风险:⚠️ 包含用户PII
2. profiles
├── 列:id, user_id, bio, website, social_links
├── 主键:id (uuid)
├── 外键:user_id → auth.users
└── 风险:⚠️ 包含用户PII
3. posts
├── 列:id, author_id, title, content, published, created_at
├── 主键:id (uuid)
└── 风险:ℹ️ 内容数据
4. comments
├── 列:id, post_id, user_id, content, created_at
├── 主键:id (uuid)
└── 风险:ℹ️ 内容数据
5. orders
├── 列:id, user_id, total, status, items, created_at
├── 主键:id (uuid)
└── 风险:🔴 包含财务/交易数据
6. products
├── 列:id, name, description, price, stock, image_url
├── 主键:id (uuid)
└── 风险:ℹ️ 公开目录数据
7. settings
├── 列:id, key, value, updated_at
├── 主键:id (uuid)
└── 风险:⚠️ 可能包含敏感配置
8. api_keys
├── 列:id, user_id, key_hash, name, last_used
├── 主键:id (uuid)
└── 风险:🔴 包含机密信息
─────────────────────────────────────────────────────────
摘要
─────────────────────────────────────────────────────────
总表数:8
高风险:2(orders, api_keys)
中风险:3(users, profiles, settings)
低风险:3(posts, comments, products)
下一步操作:
├── 运行supabase-audit-tables-read测试实际数据访问权限
├── 运行supabase-audit-rls验证RLS策略
└── 优先检查高风险表
═══════════════════════════════════════════════════════════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 |
根据表的可能内容进行分类:
| 风险 | 表特征 | 示例 |
|---|---|---|
| 🔴 高 | 财务、机密、认证相关 | orders, payments, api_keys, secrets |
| ⚠️ 中 | 用户PII、配置信息 | users, profiles, settings, preferences |
| ℹ️ 低 | 公开内容 | posts, products, categories, tags |
Context Output
上下文输出
json
{
"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"]
}
}
}json
{
"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.
═══════════════════════════════════════════════════════════有些表可能不会出现在OpenAPI schema中:
═══════════════════════════════════════════════════════════
额外发现
═══════════════════════════════════════════════════════════
常见未在Schema中显示的表(测试是否存在):
├── _prisma_migrations: ❌ 未找到
├── schema_migrations: ❌ 未找到
├── audit_log: ✅ 存在但未在OpenAPI中显示
└── internal_config: ❌ 未找到
注意:'audit_log'存在但可能访问受限。
使用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本技能还会检查非公开模式:
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 intentionalCommon 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:
sql
-- 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.
❌ 问题:未找到任何表
✅ 解决方案:
- 检查anon key是否有效
- 验证项目URL是否正确
- 项目设置中可能已禁用API
❌ 问题:列出的表过多
✅ 解决方案:这可能表明模式暴露权限过宽。建议:
sql
-- Restrict exposed schemas
ALTER ROLE anon SET search_path TO public;❌ 问题:敏感表被暴露
✅ 解决方案:将表移出public模式,或实施严格的RLS。
Recommendations by Table Type
按表类型给出的建议
User Tables
用户表
sql
-- 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);sql
-- 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
订单/支付表
sql
-- 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 operationssql
-- 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 operationsSecret Tables
机密表
sql
-- 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;sql
-- 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.
不要批量写入所有内容。而是:
- 开始任何操作前 → 将操作记录到
.sb-pentest-audit.log - 发现每个表后 → 立即更新
.sb-pentest-context.json - 完成每个重要步骤后 → 将完成情况记录到
.sb-pentest-audit.log
这样可以确保如果技能崩溃或被中断,截至该点的所有发现都已保存。
Required Actions (Progressive)
必须执行的逐步操作
-
Updatewith results:
.sb-pentest-context.jsonjson{ "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.
-
更新,写入结果:
.sb-pentest-context.jsonjson{ "tables": { "count": 8, "list": [ ... ], "by_risk": { "high": [], "medium": [], "low": [] } } } -
记录到:
.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 -
如果文件不存在,先创建再写入。
不更新上下文文件是不被允许的。
MANDATORY: Evidence Collection
强制要求:证据收集
📁 Evidence Directory:
.sb-pentest-evidence/03-api-audit/tables/📁 证据目录:
.sb-pentest-evidence/03-api-audit/tables/Evidence Files to Create
需要创建的证据文件
| File | Content |
|---|---|
| Complete list of exposed tables |
| Column details and types per table |
| Raw OpenAPI/PostgREST schema |
| 文件 | 内容 |
|---|---|
| 暴露表的完整列表 |
| 每个表的列详情和类型 |
| 原始OpenAPI/PostgREST schema |
Evidence Format
证据格式
json
{
"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
}
}json
{
"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
添加到curl-commands.sh
bash
undefinedbash
undefined=== TABLE ENUMERATION ===
=== TABLE ENUMERATION ===
List all exposed tables via OpenAPI schema
List all exposed tables via OpenAPI schema
curl -s "$SUPABASE_URL/rest/v1/" -H "apikey: $ANON_KEY"
undefinedcurl -s "$SUPABASE_URL/rest/v1/" -H "apikey: $ANON_KEY"
undefinedRelated Skills
相关技能
- — Test actual data access
supabase-audit-tables-read - — Verify RLS policies
supabase-audit-rls - — Check exposed functions
supabase-audit-rpc
- — 测试实际数据访问权限
supabase-audit-tables-read - — 验证RLS策略
supabase-audit-rls - — 检查暴露的函数
supabase-audit-rpc