supabase-extract-db-string
npx skills add https://github.com/yoanbernabeu/supabase-pentest-skills --skill supabase-extract-db-string
Agent 安装分布
Skill 文档
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.jsonIMMEDIATELY after each discovery- Log to
.sb-pentest-audit.logBEFORE 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.
When to Use This Skill
- As part of every security audit
- When reviewing code before production
- When Supabase database access is suspected
Prerequisites
- Target application accessible
- Supabase detection completed (auto-invokes if needed)
Why This Is Critical
Exposed database connection strings allow:
| Impact | Description |
|---|---|
| ð´ Direct DB Access | Bypass API, connect directly to PostgreSQL |
| ð´ Full Data Access | Read/write all data without RLS |
| ð´ Schema Access | View and modify database structure |
| ð´ User Enumeration | Access auth.users table directly |
This is a P0 (Critical) finding requiring immediate action.
Connection String Patterns
Supabase Database URL
postgresql://postgres:[password]@db.[project-ref].supabase.co:5432/postgres
Connection String Components
| Component | Example | Sensitivity |
|---|---|---|
| Host | db.abc123.supabase.co |
Medium |
| Port | 5432 |
Low |
| Database | postgres |
Low |
| Username | postgres |
Medium |
| Password | [your-password] |
ð´ Critical |
Pooler Connection (Supavisor)
postgresql://postgres.[project-ref]:[password]@aws-0-us-east-1.pooler.supabase.com:6543/postgres
Detection Patterns
1. Full Connection Strings
// â CRITICAL - Full connection string
const dbUrl = 'postgresql://postgres:MySecretPass123@db.abc123.supabase.co:5432/postgres'
2. Environment Variable Leaks
// â Exposed in client bundle
process.env.DATABASE_URL
process.env.POSTGRES_URL
process.env.SUPABASE_DB_URL
3. Partial Exposure
// â ï¸ Password exposed separately
const DB_PASSWORD = 'MySecretPass123'
const DB_HOST = 'db.abc123.supabase.co'
4. ORM Configuration
// â Database config in client code
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
Deep Scan
Deep scan for DB credentials on 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
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
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
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Context Output
{
"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
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Common Causes
| Cause | Solution |
|---|---|
| Wrong env prefix | Never use NEXT_PUBLIC_DATABASE_URL |
| SSR code in client | Ensure server-only code stays server-side |
| Bundler misconfiguration | Review webpack/vite config for env exposure |
| Copy-paste error | Double-check what you’re committing |
Architecture Guidance
Wrong (Direct DB in Client)
// â NEVER in client code
import { Pool } from 'pg'
const pool = new Pool({
connectionString: process.env.DATABASE_URL // â
})
Correct (API or 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 (Server-Side)
// 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))
})
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:
- Before starting any action â Log the action to
.sb-pentest-audit.log - After each discovery â Immediately update
.sb-pentest-context.json - 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.
Required Actions (Progressive)
-
Update
.sb-pentest-context.jsonwith findings:{ "supabase": { "db_string_exposed": true/false, "db_host": "db.[ref].supabase.co" }, "findings": [ { "id": "DB_CONNECTION_STRING_EXPOSED", "severity": "P0", ... } ] } -
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 -
If files don’t exist, create them before writing.
FAILURE TO UPDATE CONTEXT FILES IS NOT ACCEPTABLE.
MANDATORY: Evidence Collection
ð Evidence Directory: .sb-pentest-evidence/02-extraction/db-string-exposure/
Evidence Files to Create (if DB string found)
| File | Content |
|---|---|
db-string-exposure/connection-details.json |
Parsed connection string (password redacted) |
db-string-exposure/location.txt |
File path and line number |
Evidence Format (P0 Finding)
{
"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"
}
}
Add to 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**
Related Skills
supabase-extract-service-keyâ Check for service key exposuresupabase-audit-tables-readâ Test data access via APIsupabase-reportâ Generate comprehensive report