mcpField
S
supabase-extract-db-string

supabase-extract-db-string

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

supabase-extract-db-string について

supabase-extract-db-stringは、クライアント側コードに露出したPostgreSQL接続文字列やデータベース認証情報を調べるセキュリティ監査スキルです。発見事項と証拠を監査用のコンテキストファイルに記録します。

主な機能

  1. 01PostgreSQL接続文字列の検出
  2. 02漏えいしたDB環境変数の確認
  3. 03個別に露出した認証情報の検出
  4. 04クライアントコード内のORM設定を検査
  5. 05発見事項と証拠の記録

活用シーン

  1. 01WebアプリのDB認証情報漏えいを監査
  2. 02本番投入前にクライアントコードを確認
  3. 03Supabaseデータベースへのアクセスを調査

インストール

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

$npx skills add https://github.com/yoanbernabeu/supabase-pentest-skills --skill supabase-extract-db-string

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

詳細

データベース接続文字列の検出

🔴 重大:コンテキストファイルの段階的な更新が必須です

最後にまとめてではなく、作業の進行中にコンテキストファイルへ書き込む必要があります。

  • 発見事項ごとに、直ちに .sb-pentest-context.json に書き込んでください
  • 各アクションの前後に .sb-pentest-audit.log に記録してください
  • スキルの完了までファイルの更新を待たないでください
  • スキルがクラッシュしたり中断されたりした場合に備え、過去の発見事項はすべて保存済みでなければなりません

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

このスキルは、PostgreSQL データベースの接続文字列がクライアント側のコードに誤って公開されていないかを検出します。

このスキルを使用するタイミング

  • あらゆるセキュリティ監査の一環として
  • 本番環境にデプロイする前のコードレビュー時
  • Supabase のデータベースアクセスが疑われる場合

前提条件

  • 対象アプリケーションにアクセスできること
  • Supabase の検出が完了していること(必要に応じて自動実行されます)

これが重大な理由

データベース接続文字列が公開されると、次のことが可能になります。

影響説明
🔴 DB への直接アクセスAPI を迂回し、PostgreSQL に直接接続できます
🔴 すべてのデータへのアクセスRLS を介さず、すべてのデータを読み書きできます
🔴 スキーマへのアクセスデータベース構造を表示、変更できます
🔴 ユーザーの列挙auth.users テーブルに直接アクセスできます

これは P0(重大)に該当する検出事項であり、直ちに対処する必要があります。

接続文字列のパターン

Supabase データベース URL
postgresql://postgres:[password]@db.[project-ref].supabase.co:5432/postgres
接続文字列の構成要素
構成要素例機密度
ホストdb.abc123.supabase.co中
ポート5432低
データベースpostgres低
ユーザー名postgres中
パスワード[your-password]🔴 重大
プーラー接続(Supavisor)
postgresql://postgres.[project-ref]:[password]@aws-0-us-east-1.pooler.supabase.com:6543/postgres

検出パターン

1. 完全な接続文字列
// ❌ CRITICAL - Full connection string
const dbUrl = 'postgresql://postgres:[email protected]:5432/postgres'
2. 環境変数の漏洩
// ❌ Exposed in client bundle
process.env.DATABASE_URL
process.env.POSTGRES_URL
process.env.SUPABASE_DB_URL
3. 一部のみの公開
// ⚠️ Password exposed separately
const DB_PASSWORD = 'MySecretPass123'
const DB_HOST = 'db.abc123.supabase.co'
4. ORM の設定
// ❌ Database config in client code
const prisma = new PrismaClient({
  datasources: {
    db: {
      url: 'postgresql://postgres:[email protected]:5432/postgres'
    }
  }
})

使用方法

基本チェック
Check for database connection strings on https://myapp.example.com
詳細スキャン
Deep scan for DB credentials on https://myapp.example.com

出力形式

接続文字列が見つからない場合(良好)
═══════════════════════════════════════════════════════════
 DATABASE CONNECTION STRING CHECK
═══════════════════════════════════════════════════════════

 Status: ✅ No database connection strings detected

 Scanned:
 ├── JavaScript bundles: 5 files analyzed
 ├── PostgreSQL patterns: None found
 ├── Connection strings: None found
 └── Password patterns: None found

 Result: PASS - No direct database credentials exposed
═══════════════════════════════════════════════════════════
接続文字列が見つかった場合(重大)
═══════════════════════════════════════════════════════════
 🔴 CRITICAL: DATABASE CONNECTION STRING EXPOSED
═══════════════════════════════════════════════════════════

 Severity: P0 - CRITICAL
 Status: ❌ PostgreSQL connection string found in client code!

 ⚠️  IMMEDIATE ACTION REQUIRED ⚠️

 Connection String:
 postgresql://postgres:MySecr***@db.abc123def.supabase.co:5432/postgres
 (Password partially redacted in display, full value in context file)

 Parsed Components:
 ├── Host: db.abc123def.supabase.co
 ├── Port: 5432
 ├── Database: postgres
 ├── Username: postgres
 └── Password: [EXPOSED] ← CRITICAL

 Location:
 └── /static/js/api.chunk.js (line 234)
     const DATABASE_URL = 'postgresql://postgres:...'

 Impact Assessment:
 ├── 🔴 Direct PostgreSQL access possible
 ├── 🔴 All RLS policies bypassed
 ├── 🔴 Can access auth.users table
 ├── 🔴 Can modify database schema
 └── 🔴 Full data exfiltration possible

 ═══════════════════════════════════════════════════════════
 IMMEDIATE REMEDIATION STEPS
 ═══════════════════════════════════════════════════════════

 1. CHANGE DATABASE PASSWORD NOW
    → Supabase Dashboard > Settings > Database > Reset database password

 2. REMOVE FROM CLIENT CODE
    → Delete connection string from source code
    → Ensure DATABASE_URL is not in NEXT_PUBLIC_* or VITE_* env vars
    → Redeploy application

 3. AUDIT FOR ABUSE
    → Check Supabase logs for direct PostgreSQL connections
    → Review for unauthorized data access or modifications

 4. USE PROPER ARCHITECTURE
    → Client should ONLY use Supabase client library (REST API)
    → Direct DB access should ONLY be from:
      - Edge Functions
      - Server-side code
      - Migration tools

 Documentation:
 → https://supabase.com/docs/guides/database/connecting-to-postgres
 → https://supabase.com/docs/guides/functions

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

コンテキスト出力

{
  "findings": [
    {
      "id": "DB_CONNECTION_STRING_EXPOSED",
      "severity": "P0",
      "title": "PostgreSQL Connection String Exposed",
      "description": "Database connection string with password found in client-side code",
      "location": {
        "file": "/static/js/api.chunk.js",
        "line": 234
      },
      "evidence": {
        "host": "db.abc123def.supabase.co",
        "port": 5432,
        "database": "postgres",
        "username": "postgres",
        "password_exposed": true
      },
      "remediation": {
        "immediate": "Reset database password in Supabase Dashboard",
        "long_term": "Move DB operations to Edge Functions",
        "docs": "https://supabase.com/docs/guides/database/connecting-to-postgres"
      }
    }
  ],
  "supabase": {
    "db_string_exposed": true,
    "db_host": "db.abc123def.supabase.co"
  }
}

一部のみの公開

一部のみの公開でも懸念が残ります。

═══════════════════════════════════════════════════════════
 ⚠️ PARTIAL DATABASE CREDENTIALS FOUND
═══════════════════════════════════════════════════════════

 Severity: P1 - High

 Found:
 ├── Database host: db.abc123def.supabase.co (line 45)
 ├── Database password: [16 char string] (line 89)
 └── Could potentially be combined for access

 Recommendation:
 → Rotate database password as precaution
 → Remove all DB-related values from client code
═══════════════════════════════════════════════════════════

よくある原因

原因解決策
環境変数のプレフィックスの誤りNEXT_PUBLIC_DATABASE_URL は決して使用しないでください
クライアント側の SSR コードサーバー専用コードがサーバー側にとどまるようにしてください
バンドラーの設定ミス環境変数の公開について webpack/vite の設定を確認してください
コピー&ペーストのミスコミットする内容を必ず再確認してください

アーキテクチャの指針

誤り(クライアントから DB に直接接続)
// ❌ NEVER in client code
import { Pool } from 'pg'
const pool = new Pool({
  connectionString: process.env.DATABASE_URL  // ❌
})
正しい方法(API または Edge Function)
// ✅ Client uses Supabase client
const { data } = await supabase
  .from('products')
  .select('*')

// OR call an Edge Function for complex queries
const { data } = await supabase.functions.invoke('complex-query')
Edge Function(サーバー側)
// supabase/functions/complex-query/index.ts
import { createClient } from '@supabase/supabase-js'

Deno.serve(async (req) => {
  // ✅ Direct DB access only on server
  const supabase = createClient(
    Deno.env.get('SUPABASE_URL'),
    Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')
  )

  // Complex query that can't be done via REST
  const { data } = await supabase.rpc('complex_function')
  return new Response(JSON.stringify(data))
})

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

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

重要なルール:作業の進行中に書き込む

最後にまとめて書き込むことはしないでください。代わりに、次の手順に従ってください。

  1. アクションを開始する前に → .sb-pentest-audit.log にアクションを記録します
  2. 発見事項ごとに → 直ちに .sb-pentest-context.json を更新します
  3. 重要な手順ごとに → 完了したことを .sb-pentest-audit.log に記録します

これにより、スキルが中断されたり、クラッシュしたり、タイムアウトした場合でも、その時点までのすべての検出事項が保持されます。

必須アクション(段階的に実施)
  1. 検出事項を .sb-pentest-context.json に更新します。

    {
      "supabase": {
        "db_string_exposed": true/false,
        "db_host": "db.[ref].supabase.co"
      },
      "findings": [
        {
          "id": "DB_CONNECTION_STRING_EXPOSED",
          "severity": "P0",
          ...
        }
      ]
    }
    
  2. .sb-pentest-audit.log に記録します。

    [TIMESTAMP] [supabase-extract-db-string] [START] Checking for DB connection strings
    [TIMESTAMP] [supabase-extract-db-string] [CRITICAL] Connection string EXPOSED
    [TIMESTAMP] [supabase-extract-db-string] [CONTEXT_UPDATED] .sb-pentest-context.json updated
    
  3. ファイルが存在しない場合は、書き込み前に作成します。

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

必須:証拠の収集

📁 証拠ディレクトリ: .sb-pentest-evidence/02-extraction/db-string-exposure/

作成する証拠ファイル(DB 文字列が見つかった場合)
ファイル内容
db-string-exposure/connection-details.json解析済みの接続文字列(パスワードは伏せ字)
db-string-exposure/location.txtファイルパスと行番号
証拠の形式(P0 検出事項)
{
  "evidence_id": "EXT-DB-001",
  "timestamp": "2025-01-31T10:12:00Z",
  "category": "extraction",
  "type": "db_connection_string",
  "severity": "P0",
  "finding_id": "P0-002",

  "connection_string": {
    "pattern": "postgresql://postgres:[REDACTED]@db.abc123def.supabase.co:5432/postgres",
    "host": "db.abc123def.supabase.co",
    "port": 5432,
    "database": "postgres",
    "username": "postgres",
    "password_exposed": true,
    "password_length": 24
  },

  "location": {
    "file": "/static/js/api.chunk.js",
    "line": 234,
    "context": "const DATABASE_URL = 'postgresql://postgres:...' // [REDACTED]"
  },

  "impact": {
    "direct_db_access": true,
    "rls_bypass": true,
    "schema_access": true,
    "auth_users_access": true
  },

  "remediation": {
    "immediate": "Reset database password in Supabase Dashboard",
    "remove_from_code": "Delete DATABASE_URL from client code",
    "verify_env_vars": "Ensure not using NEXT_PUBLIC_DATABASE_URL or similar"
  }
}
timeline.md への追記(P0)
## [TIMESTAMP] - 🔴 P0 CRITICAL: Database Connection String Exposed
- PostgreSQL connection string with password found in client code
- Location: [file]:[line]
- Impact: Direct database access, full RLS bypass
- Evidence: `02-extraction/db-string-exposure/`
- **IMMEDIATE PASSWORD ROTATION REQUIRED**

関連スキル

  • supabase-extract-service-key — サービスキーの露出を確認します
  • supabase-audit-tables-read — API 経由でデータアクセスをテストします
  • supabase-report — 包括的なレポートを生成します

コメント