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. 01检测完整 PostgreSQL 连接字符串
  2. 02查找泄露的数据库环境变量
  3. 03标记单独暴露的凭据
  4. 04扫描客户端 ORM 配置
  5. 05记录发现与证据

适用场景

  1. 01审计 Web 应用中的数据库凭据泄露
  2. 02上线前检查客户端代码
  3. 03调查疑似 Supabase 数据库访问问题

安装

复制下面的命令,在终端中运行。

$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 检测(如有需要会自动调用)

为什么这很重要

暴露数据库连接字符串会导致:

影响说明
🔴 直接访问数据库绕过 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]🔴 严重
Pooler 连接(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 配置,确认没有暴露环境变量
复制粘贴错误仔细检查要提交的内容

架构指导

错误(在客户端直接访问数据库)
// ❌ 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-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 — 生成全面报告

评论

支持 Markdown