supabase-extract-db-string

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Database Connection String Detection

数据库连接字符串检测

🔴 CRITICAL: PROGRESSIVE FILE UPDATES REQUIRED
You MUST write to context files AS YOU GO, not just at the end.
  • Write to
    .sb-pentest-context.json
    IMMEDIATELY after each discovery
  • Log to
    .sb-pentest-audit.log
    BEFORE and AFTER each action
  • 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 detects if PostgreSQL database connection strings are accidentally exposed in client-side code.
🔴 严重级别:必须逐步更新文件
你必须逐步写入上下文文件,而不是只在最后写入。
  • 每次发现后立即写入
    .sb-pentest-context.json
  • 在每次操作前后记录到
    .sb-pentest-audit.log
  • 不要等到技能完成后才更新文件
  • 如果技能崩溃或被中断,所有之前的发现必须已保存
这不是可选要求。不逐步写入属于严重错误。
该技能用于检测客户端代码中是否意外暴露了PostgreSQL数据库连接字符串。

When to Use This Skill

何时使用该技能

  • As part of every security audit
  • When reviewing code before production
  • When Supabase database access is suspected
  • 作为每次安全审计的一部分
  • 上线前审查代码时
  • 怀疑Supabase数据库访问存在风险时

Prerequisites

前置条件

  • Target application accessible
  • Supabase detection completed (auto-invokes if needed)
  • 可访问目标应用
  • 已完成Supabase检测(如需会自动调用)

Why This Is Critical

为何这至关重要

Exposed database connection strings allow:
ImpactDescription
🔴 Direct DB AccessBypass API, connect directly to PostgreSQL
🔴 Full Data AccessRead/write all data without RLS
🔴 Schema AccessView and modify database structure
🔴 User EnumerationAccess auth.users table directly
This is a P0 (Critical) finding requiring immediate action.
暴露的数据库连接字符串会导致:
影响描述
🔴 直接数据库访问绕过API,直接连接PostgreSQL
🔴 全数据访问无需RLS即可读写所有数据
🔴 架构访问查看并修改数据库结构
🔴 用户枚举直接访问auth.users表
这是需要立即处理的P0(严重)级问题。

Connection String Patterns

连接字符串模式

Supabase Database URL

Supabase数据库URL

postgresql://postgres:[password]@db.[project-ref].supabase.co:5432/postgres
postgresql://postgres:[password]@db.[project-ref].supabase.co:5432/postgres

Connection String Components

连接字符串组件

ComponentExampleSensitivity
Host
db.abc123.supabase.co
Medium
Port
5432
Low
Database
postgres
Low
Username
postgres
Medium
Password
[your-password]
🔴 Critical
组件示例敏感度
主机
db.abc123.supabase.co
中等
端口
5432
数据库
postgres
用户名
postgres
中等
密码
[your-password]
🔴 严重

Pooler Connection (Supavisor)

池化连接(Supavisor)

postgresql://postgres.[project-ref]:[password]@aws-0-us-east-1.pooler.supabase.com:6543/postgres
postgresql://postgres.[project-ref]:[password]@aws-0-us-east-1.pooler.supabase.com:6543/postgres

Detection Patterns

检测模式

1. Full Connection Strings

1. 完整连接字符串

javascript
// ❌ CRITICAL - Full connection string
const dbUrl = 'postgresql://postgres:MySecretPass123@db.abc123.supabase.co:5432/postgres'
javascript
// ❌ 严重 - 完整连接字符串
const dbUrl = 'postgresql://postgres:MySecretPass123@db.abc123.supabase.co:5432/postgres'

2. Environment Variable Leaks

2. 环境变量泄露

javascript
// ❌ Exposed in client bundle
process.env.DATABASE_URL
process.env.POSTGRES_URL
process.env.SUPABASE_DB_URL
javascript
// ❌ 在客户端包中暴露
process.env.DATABASE_URL
process.env.POSTGRES_URL
process.env.SUPABASE_DB_URL

3. Partial Exposure

3. 部分信息暴露

javascript
// ⚠️ Password exposed separately
const DB_PASSWORD = 'MySecretPass123'
const DB_HOST = 'db.abc123.supabase.co'
javascript
// ⚠️ 密码单独暴露
const DB_PASSWORD = 'MySecretPass123'
const DB_HOST = 'db.abc123.supabase.co'

4. ORM Configuration

4. ORM配置

javascript
// ❌ Database config in client code
const prisma = new PrismaClient({
  datasources: {
    db: {
      url: 'postgresql://postgres:pass@db.abc123.supabase.co:5432/postgres'
    }
  }
})
javascript
// ❌ 客户端代码中的数据库配置
const prisma = new PrismaClient({
  datasources: {
    db: {
      url: 'postgresql://postgres:pass@db.abc123.supabase.co:5432/postgres'
    }
  }
})

Usage

使用方法

Basic Check

基础检查

Check for database connection strings on https://myapp.example.com
检查https://myapp.example.com上的数据库连接字符串

Deep Scan

深度扫描

Deep scan for DB credentials on https://myapp.example.com
对https://myapp.example.com进行深度扫描以查找数据库凭证

Output Format

输出格式

No Connection String Found (Good)

未找到连接字符串(正常)

═══════════════════════════════════════════════════════════
 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
═══════════════════════════════════════════════════════════
═══════════════════════════════════════════════════════════
 数据库连接字符串检查
═══════════════════════════════════════════════════════════

 状态:✅ 未检测到数据库连接字符串

 扫描内容:
 ├── JavaScript包:已分析5个文件
 ├── PostgreSQL模式:未找到
 ├── 连接字符串:未找到
 └── 密码模式:未找到

 结果:通过 - 未暴露直接数据库凭证
═══════════════════════════════════════════════════════════

Connection String FOUND (Critical)

找到连接字符串(严重)

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

═══════════════════════════════════════════════════════════
═══════════════════════════════════════════════════════════
 🔴 严重:数据库连接字符串已暴露
═══════════════════════════════════════════════════════════

 严重级别:P0 - 严重
 状态:❌ 在客户端代码中发现PostgreSQL连接字符串!

 ⚠️ 需立即采取行动 ⚠️

 连接字符串:
 postgresql://postgres:MySecr***@db.abc123def.supabase.co:5432/postgres
 (显示时密码已部分脱敏,完整值已保存到上下文文件)

 解析后的组件:
 ├── 主机:db.abc123def.supabase.co
 ├── 端口:5432
 ├── 数据库:postgres
 ├── 用户名:postgres
 └── 密码:[已暴露] ← 严重

 位置:
 └── /static/js/api.chunk.js(第234行)
     const DATABASE_URL = 'postgresql://postgres:...'

 影响评估:
 ├── 🔴 可直接访问PostgreSQL
 ├── 🔴 所有RLS策略被绕过
 ├── 🔴 可访问auth.users表
 ├── 🔴 可修改数据库架构
 └── 🔴 可完全泄露数据

 ═══════════════════════════════════════════════════════════
 立即修复步骤
 ═══════════════════════════════════════════════════════════

 1. 立即更改数据库密码
    → Supabase控制台 > 设置 > 数据库 > 重置数据库密码

 2. 从客户端代码中移除
    → 从源代码中删除连接字符串
    → 确保DATABASE_URL不在NEXT_PUBLIC_*或VITE_*环境变量中
    → 重新部署应用

 3. 审计是否被滥用
    → 检查Supabase日志中的直接PostgreSQL连接记录
    → 审查是否存在未授权的数据访问或修改

 4. 使用正确的架构
    → 客户端应仅使用Supabase客户端库(REST API)
    → 仅允许以下场景直接访问数据库:
      - Edge Functions
      - 服务端代码
      - 迁移工具

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

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

Context Output

上下文输出

json
{
  "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"
  }
}
json
{
  "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 Exposure

部分信息暴露

Even partial exposure is concerning:
═══════════════════════════════════════════════════════════
 ⚠️ 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
═══════════════════════════════════════════════════════════
即使是部分信息暴露也需重视:
═══════════════════════════════════════════════════════════
 ⚠️ 发现部分数据库凭证
═══════════════════════════════════════════════════════════

 严重级别:P1 - 高

 发现内容:
 ├── 数据库主机:db.abc123def.supabase.co(第45行)
 ├── 数据库密码:[16位字符串](第89行)
 └── 这些信息可能被组合用于访问数据库

 建议:
 → 作为预防措施,轮换数据库密码
 → 从客户端代码中移除所有与数据库相关的值
═══════════════════════════════════════════════════════════

Common Causes

常见原因

CauseSolution
Wrong env prefixNever use
NEXT_PUBLIC_DATABASE_URL
SSR code in clientEnsure server-only code stays server-side
Bundler misconfigurationReview webpack/vite config for env exposure
Copy-paste errorDouble-check what you're committing
原因解决方案
错误的环境变量前缀永远不要使用
NEXT_PUBLIC_DATABASE_URL
SSR代码出现在客户端确保仅服务端代码留在服务端
打包工具配置错误审查webpack/vite配置中的环境变量暴露情况
复制粘贴错误仔细检查提交的内容

Architecture Guidance

架构指导

Wrong (Direct DB in Client)

错误示例(客户端直接访问数据库)

javascript
// ❌ NEVER in client code
import { Pool } from 'pg'
const pool = new Pool({
  connectionString: process.env.DATABASE_URL  // ❌
})
javascript
// ❌ 绝不能出现在客户端代码中
import { Pool } from 'pg'
const pool = new Pool({
  connectionString: process.env.DATABASE_URL  // ❌
})

Correct (API or Edge Function)

正确示例(API或Edge Function)

javascript
// ✅ 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')
javascript
// ✅ 客户端使用Supabase客户端
const { data } = await supabase
  .from('products')
  .select('*')

// 或调用Edge Function执行复杂查询
const { data } = await supabase.functions.invoke('complex-query')

Edge Function (Server-Side)

Edge Function(服务端)

typescript
// 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))
})
typescript
// supabase/functions/complex-query/index.ts
import { createClient } from '@supabase/supabase-js'

Deno.serve(async (req) => {
  // ✅ 仅服务端可直接访问数据库
  const supabase = createClient(
    Deno.env.get('SUPABASE_URL'),
    Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')
  )

  // 无法通过REST API完成的复杂查询
  const { data } = await supabase.rpc('complex_function')
  return new Response(JSON.stringify(data))
})

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:
  1. Before starting any action → Log the action to
    .sb-pentest-audit.log
  2. After each discovery → Immediately update
    .sb-pentest-context.json
  3. 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.
不要批量在最后写入。而是:
  1. 开始任何操作前 → 将操作记录到
    .sb-pentest-audit.log
  2. 每次发现后 → 立即更新
    .sb-pentest-context.json
  3. 完成每个重要步骤后 → 将完成情况记录到
    .sb-pentest-audit.log
这样可以确保如果技能被中断、崩溃或超时,截至该点的所有发现都已保存。

Required Actions (Progressive)

强制操作(逐步执行)

  1. Update
    .sb-pentest-context.json
    with findings:
    json
    {
      "supabase": {
        "db_string_exposed": true/false,
        "db_host": "db.[ref].supabase.co"
      },
      "findings": [
        {
          "id": "DB_CONNECTION_STRING_EXPOSED",
          "severity": "P0",
          ...
        }
      ]
    }
  2. Log to
    .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. If files don't exist, create them before writing.
FAILURE TO UPDATE CONTEXT FILES IS NOT ACCEPTABLE.
  1. **更新
    .sb-pentest-context.json
    **以记录发现:
    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] 正在检查数据库连接字符串
    [TIMESTAMP] [supabase-extract-db-string] [CRITICAL] 连接字符串已暴露
    [TIMESTAMP] [supabase-extract-db-string] [CONTEXT_UPDATED] .sb-pentest-context.json已更新
  3. 如果文件不存在,在写入前创建。
不更新上下文文件是不被允许的。

MANDATORY: Evidence Collection

强制要求:证据收集

📁 Evidence Directory:
.sb-pentest-evidence/02-extraction/db-string-exposure/
📁 证据目录:
.sb-pentest-evidence/02-extraction/db-string-exposure/

Evidence Files to Create (if DB string found)

需创建的证据文件(如果发现数据库字符串)

FileContent
db-string-exposure/connection-details.json
Parsed connection string (password redacted)
db-string-exposure/location.txt
File path and line number
文件内容
db-string-exposure/connection-details.json
解析后的连接字符串(密码已脱敏)
db-string-exposure/location.txt
文件路径和行号

Evidence Format (P0 Finding)

证据格式(P0级发现)

json
{
  "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"
  }
}
json
{
  "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": "在Supabase控制台重置数据库密码",
    "remove_from_code": "从客户端代码中删除DATABASE_URL",
    "verify_env_vars": "确保未使用NEXT_PUBLIC_DATABASE_URL或类似变量"
  }
}

Add to timeline.md (P0)

添加到timeline.md(P0级)

markdown
undefined
markdown
undefined

[TIMESTAMP] - 🔴 P0 CRITICAL: Database Connection String Exposed

[TIMESTAMP] - 🔴 P0严重:数据库连接字符串已暴露

  • 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
undefined
  • 在客户端代码中发现带密码的PostgreSQL连接字符串
  • 位置:[文件]:[行号]
  • 影响:直接访问数据库,完全绕过RLS
  • 证据:
    02-extraction/db-string-exposure/
  • 需立即轮换密码
undefined

Related Skills

相关技能

  • supabase-extract-service-key
    — Check for service key exposure
  • supabase-audit-tables-read
    — Test data access via API
  • supabase-report
    — Generate comprehensive report
  • supabase-extract-service-key
    — 检查服务密钥是否暴露
  • supabase-audit-tables-read
    — 通过API测试数据访问权限
  • supabase-report
    — 生成综合报告