Supabase表审计列表Skill supabase-audit-tables-list

此技能用于通过 Supabase PostgREST API 列出所有暴露的数据库表,以识别攻击面并进行安全审计,适用于渗透测试和风险评估。关键词:Supabase、审计、数据库表、API 安全、渗透测试、安全评估。

安全审计 0 次安装 0 次浏览 更新于 3/18/2026

名称: supabase-audit-tables-list 描述: 通过 Supabase PostgREST API 列出所有暴露的表以识别攻击面。

列出暴露的表

🔴 关键: 需要渐进式文件更新

您必须逐步写入上下文文件,而不仅仅是在结束时。

  • 每次发现后立即写入 .sb-pentest-context.json
  • 每次操作前后记录到 .sb-pentest-audit.log
  • 不要等待技能完成再更新文件
  • 如果技能崩溃或中断,所有先前发现必须已保存

这不是可选的。未逐步写入是关键错误。

此技能发现通过 Supabase PostgREST API 暴露的所有数据库表。

何时使用此技能

  • 理解 API 攻击面
  • 测试 RLS 策略前
  • 清点暴露的数据模型
  • 作为全面安全审计的一部分

先决条件

  • 提取的 Supabase URL(如果需要,自动调用)
  • 提取的 Anon 密钥(如果需要,自动调用)

工作原理

Supabase 通过 PostgREST 暴露表:

https://[项目引用].supabase.co/rest/v1/

技能使用 OpenAPI 模式端点枚举表:

https://[项目引用].supabase.co/rest/v1/?apikey=[anon-key]

暴露内容

默认情况下,Supabase 暴露 public 模式中的表。表在以下情况下暴露:

  1. 它们存在于暴露的模式中(默认:public
  2. 未执行显式 REVOKE
  3. PostgREST 可以看见它们

用法

基本表列表

列出我的 Supabase 项目上暴露的表

带模式信息

列出所有暴露的表及其列详细信息

输出格式

═══════════════════════════════════════════════════════════
 暴露的表
═══════════════════════════════════════════════════════════

 项目: 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 策略
 └── 首先审查高风险表

═══════════════════════════════════════════════════════════

风险分类

表根据可能内容分类:

风险 表模式 示例
🔴 高 财务、机密、认证 orders, payments, api_keys, secrets
⚠️ 中 用户 PII、配置 users, profiles, settings, preferences
ℹ️ 低 公共内容 posts, products, categories, tags

上下文输出

{
  "tables": {
    "count": 8,
    "list": [
      {
        "name": "users",
        "schema": "public",
        "columns": ["id", "email", "name", "avatar_url", "created_at"],
        "primary_key": "id",
        "risk_level": "medium",
        "risk_reason": "包含用户 PII"
      },
      {
        "name": "orders",
        "schema": "public",
        "columns": ["id", "user_id", "total", "status", "items", "created_at"],
        "primary_key": "id",
        "risk_level": "high",
        "risk_reason": "包含财务数据"
      }
    ],
    "by_risk": {
      "high": ["orders", "api_keys"],
      "medium": ["users", "profiles", "settings"],
      "low": ["posts", "comments", "products"]
    }
  }
}

隐藏表

某些表可能未出现在 OpenAPI 模式中:

═══════════════════════════════════════════════════════════
 额外发现
═══════════════════════════════════════════════════════════

 模式中常见的未列出表(测试存在性):
 ├── _prisma_migrations: ❌ 未找到
 ├── schema_migrations: ❌ 未找到
 ├── audit_log: ✅ 存在但不在 OpenAPI 中
 └── internal_config: ❌ 未找到

 注意: 'audit_log' 存在但可能访问受限。
       使用 supabase-audit-tables-read 测试。
═══════════════════════════════════════════════════════════

模式分析

技能还检查非公共模式:

模式暴露检查:
├── public: ✅ 暴露 (8 表)
├── auth: ❌ 未直接暴露(预期)
├── storage: ❌ 未直接暴露(预期)
├── extensions: ❌ 未暴露(好)
└── custom_schema: ⚠️ 暴露 (3 表) - 审查是否故意

常见问题

问题: 未找到表 ✅ 解决方案:

  • 检查 anon 密钥是否有效
  • 验证项目 URL 正确
  • API 可能在项目设置中禁用

问题: 列出太多表 ✅ 解决方案: 这可能表示模式暴露过于宽松。考虑:

-- 限制暴露的模式
ALTER ROLE anon SET search_path TO public;

问题: 敏感表暴露 ✅ 解决方案: 要么从公共模式中移除,要么实施严格的 RLS。

按表类型推荐

用户表

-- 确保启用 RLS
ALTER TABLE users ENABLE ROW LEVEL SECURITY;

-- 用户只能查看自己的数据
CREATE POLICY "用户查看自己数据" ON users
  FOR SELECT USING (auth.uid() = id);

订单/支付表

-- 对财务数据实施严格 RLS
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

CREATE POLICY "用户查看自己订单" ON orders
  FOR SELECT USING (auth.uid() = user_id);

-- 即使管理员也禁止通过 API 公共访问
-- 使用 Edge Functions 进行管理操作

机密表

-- 考虑完全不暴露
REVOKE ALL ON TABLE api_keys FROM anon, authenticated;

-- 或使用隐藏敏感列的视图
CREATE VIEW public.api_keys_safe AS
  SELECT id, name, last_used FROM api_keys;

强制: 渐进式上下文文件更新

⚠️ 此技能必须在执行期间渐进式更新跟踪文件,而不仅仅在结束时。

关键规则: 逐步写入

不要在结束时批量写入所有内容。而是:

  1. 开始任何操作前 → 记录操作到 .sb-pentest-audit.log
  2. 每次发现表后 → 立即更新 .sb-pentest-context.json
  3. 每次重要步骤后 → 记录完成到 .sb-pentest-audit.log

这确保如果技能中断、崩溃或超时,所有先前发现都已保存。

所需操作(渐进式)

  1. 更新 .sb-pentest-context.json 包含结果:

    {
      "tables": {
        "count": 8,
        "list": [ ... ],
        "by_risk": { "high": [], "medium": [], "low": [] }
      }
    }
    
  2. 记录到 .sb-pentest-audit.log:

    [时间戳] [supabase-audit-tables-list] [开始] 列出暴露的表
    [时间戳] [supabase-audit-tables-list] [成功] 发现 8 表
    [时间戳] [supabase-audit-tables-list] [上下文已更新] .sb-pentest-context.json 已更新
    
  3. 如果文件不存在,写入前创建。

未更新上下文文件是不可接受的。

强制: 证据收集

📁 证据目录: .sb-pentest-evidence/03-api-audit/tables/

要创建的证据文件

文件 内容
tables-list.json 暴露表的完整列表
tables-metadata.json 每表的列详细信息和类型
openapi-schema.json 原始 OpenAPI/PostgREST 模式

证据格式

{
  "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": "[已隐藏]"
    },
    "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": "包含 PII"
    },
    {
      "name": "orders",
      "schema": "public",
      "columns": ["id", "user_id", "total", "status"],
      "primary_key": "id",
      "risk_level": "high",
      "risk_reason": "财务数据"
    }
  ],

  "summary": {
    "total_tables": 8,
    "high_risk": 2,
    "medium_risk": 3,
    "low_risk": 3
  }
}

添加到 curl-commands.sh

# === 表枚举 ===
# 通过 OpenAPI 模式列出所有暴露的表
curl -s "$SUPABASE_URL/rest/v1/" -H "apikey: $ANON_KEY"

相关技能

  • supabase-audit-tables-read — 测试实际数据访问
  • supabase-audit-rls — 验证 RLS 策略
  • supabase-audit-rpc — 检查暴露的函数