mcpField
S
supabase-audit-tables-list

supabase-audit-tables-list

github.com/yoanbernabeuセキュリティ71489 回インストール39 週間前に更新
リポジトリ

supabase-audit-tables-list について

Supabase PostgREST API で公開されるデータベーステーブルを調べる監査スキルです。OpenAPI スキーマからテーブルや列を列挙し、スキーマの公開状況とリスクを確認して結果を逐次記録します。

主な機能

  1. 01PostgREST の OpenAPI スキーマからテーブルを列挙
  2. 02スキーマと列の詳細を収集
  3. 03非公開スキーマの公開状況を確認
  4. 04テーブルを想定リスク別に分類し証拠を保存
  5. 05コンテキストと監査ログを逐次更新

活用シーン

  1. 01RLS ポリシーの検査前に API の攻撃対象領域を把握
  2. 02プロジェクトで公開されているテーブルとスキーマを監査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/yoanbernabeu/supabase-pentest-skills --skill supabase-audit-tables-list

インストール後、Claude Code で/supabase-audit-tables-listを入力して読み込まれたか確認します。

詳細

公開テーブルの一覧

🔴 重大:コンテキストファイルを段階的に更新する必要があります

コンテキストファイルには、最後にまとめてではなく、作業を進めながら必ず書き込んでください。

  • 発見するたびに、.sb-pentest-context.json に直ちに書き込んでください
  • 各アクションの前後に .sb-pentest-audit.log に記録してください
  • スキルの完了までファイルの更新を待たないでください
  • スキルがクラッシュまたは中断された場合でも、それまでの調査結果がすべて保存されている必要があります

これは任意ではありません。段階的な書き込みを行わないことは重大なエラーです。

このスキルは、Supabase PostgREST API を通じて公開されているすべてのデータベーステーブルを検出します。

このスキルを使用する場面

  • API の攻撃対象領域を把握する場合
  • RLS ポリシーをテストする前
  • 公開されているデータモデルを一覧化する場合
  • 包括的なセキュリティ監査の一環として

前提条件

  • Supabase URL が抽出済み(必要に応じて自動で呼び出されます)
  • Anon key が抽出済み(必要に応じて自動で呼び出されます)

仕組み

Supabase は、以下の PostgREST を通じてテーブルを公開します。

https://[project-ref].supabase.co/rest/v1/

このスキルは、OpenAPI スキーマエンドポイントを使用してテーブルを列挙します。

https://[project-ref].supabase.co/rest/v1/?apikey=[anon-key]

公開されるもの

デフォルトでは、Supabase は public スキーマ内のテーブルを公開します。テーブルが公開されるのは、次の条件を満たす場合です。

  1. 公開対象のスキーマ(デフォルト:public)に存在する
  2. 明示的な REVOKE が実行されていない
  3. PostgREST から参照できる

使用方法

基本的なテーブル一覧
List tables exposed on my Supabase project
スキーマ情報付き
List all exposed tables with column details

出力形式

═══════════════════════════════════════════════════════════
 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

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

リスク分類

テーブルは、含まれている可能性の高いデータに基づいて分類されます。

リスクテーブルのパターン例
🔴 高財務、秘密情報、認証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": "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"]
    }
  }
}

非表示のテーブル

一部のテーブルは OpenAPI スキーマに表示されないことがあります。

═══════════════════════════════════════════════════════════
 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.
═══════════════════════════════════════════════════════════

スキーマ分析

このスキルは、public 以外のスキーマも確認します。

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

よくある問題

❌ 問題: テーブルが見つからない ✅ 解決策:

  • Anon key が有効か確認する
  • プロジェクト URL が正しいか確認する
  • プロジェクト設定で API が無効になっている可能性があります

❌ 問題: テーブルが多すぎる ✅ 解決策: スキーマの公開範囲が過度に広い可能性があります。次の対応を検討してください。

-- Restrict exposed schemas
ALTER ROLE anon SET search_path TO public;

❌ 問題: 機密テーブルが公開されている ✅ 解決策: public スキーマから削除するか、厳格な RLS を実装してください。

テーブルの種類別の推奨事項

ユーザーテーブル
-- 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);
注文/決済テーブル
-- 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
秘密情報テーブル
-- 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;

必須:コンテキストファイルの段階的な更新

⚠️ このスキルは、実行中に追跡ファイルを段階的に更新する必要があります。最後にまとめて更新してはいけません。

重要なルール:作業を進めながら書き込む

すべての書き込みを最後にまとめて行わないでください。代わりに、次の手順を実行してください。

  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 に記録します。

    [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
    
  3. ファイルが存在しない場合は、書き込む前に作成します。

コンテキストファイルを更新しないことは許容されません。

必須:証拠の収集

📁 証拠ディレクトリ: .sb-pentest-evidence/03-api-audit/tables/

作成する証拠ファイル
ファイル内容
tables-list.json公開されているテーブルの完全な一覧
tables-metadata.jsonテーブルごとの列の詳細と型
openapi-schema.jsonOpenAPI/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": "[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
  }
}
curl-commands.sh に追加
# === TABLE ENUMERATION ===
# List all exposed tables via OpenAPI schema
curl -s "$SUPABASE_URL/rest/v1/" -H "apikey: $ANON_KEY"

関連スキル

  • supabase-audit-tables-read — 実際のデータアクセスをテストします
  • supabase-audit-rls — RLS ポリシーを確認します
  • supabase-audit-rpc — 公開されている関数を確認します

コメント