supabase-evidence
npx skills add https://github.com/yoanbernabeu/supabase-pentest-skills --skill supabase-evidence
Agent 安装分布
Skill 文档
Evidence Collection Management
ð´ CRITICAL: PROGRESSIVE FILE UPDATES REQUIRED
You MUST write evidence files AS YOU GO, not just at the end.
- Save each piece of evidence IMMEDIATELY after collection
- DO NOT wait until the skill completes to save evidence
- If the audit crashes or is interrupted, all prior evidence must already be saved
This is not optional. Failure to save evidence progressively is a critical error.
This skill initializes and manages the evidence collection system for professional security audits.
When to Use This Skill
- Automatically invoked at the start of
supabase-pentest - When you need to organize evidence for a professional report
- When conducting audits that require documented proof
- For compliance and legal purposes
Why Evidence Collection Matters
Professional security audits require:
| Requirement | Purpose |
|---|---|
| Reproducibility | Others can verify findings |
| Legal proof | Documentation for legal/compliance |
| Remediation verification | Prove issues existed before fix |
| Audit trail | Complete record of what was tested |
Evidence Directory Structure
The skill creates .sb-pentest-evidence/ with this structure:
.sb-pentest-evidence/
âââ README.md # Evidence index and summary
âââ curl-commands.sh # All curl commands used (reproducible)
âââ timeline.md # Chronological evidence timeline
â
âââ 01-detection/
â âââ initial-scan.json # Raw detection results
â âââ supabase-endpoints.txt # Discovered endpoints
â âââ client-code-snippets/ # Relevant code excerpts
â âââ supabase-init.js
â
âââ 02-extraction/
â âââ extracted-url.json # URL extraction proof
â âââ extracted-anon-key.json # Anon key with decoded JWT
â âââ extracted-jwts.json # All JWTs found
â âââ service-key-exposure/ # If service key found (P0)
â â âââ location.txt
â â âââ decoded-payload.json
â âââ db-string-exposure/ # If DB string found (P0)
â âââ connection-details.json
â
âââ 03-api-audit/
â âââ openapi-schema.json # Raw OpenAPI/PostgREST schema
â âââ tables/
â â âââ tables-list.json # All exposed tables
â â âââ tables-metadata.json # Column details per table
â âââ data-samples/ # Sample data retrieved (redacted)
â â âââ users-sample.json
â â âââ orders-sample.json
â â âââ ...
â âââ rls-tests/ # RLS policy test results
â â âââ users-anon.json # Anon access attempt
â â âââ users-auth.json # Authenticated access
â â âââ cross-user-test.json # Cross-user access attempt
â âââ rpc-tests/ # RPC function test results
â âââ function-list.json
â âââ vulnerable-functions/
â âââ get-all-users.json
â
âââ 04-storage-audit/
â âââ buckets-config.json # Bucket configurations
â âââ buckets/
â â âââ avatars/
â â â âââ file-list.json
â â âââ backups/ # If sensitive (P0)
â â â âââ file-list.json
â â â âââ sample-contents/ # Redacted samples
â â âââ ...
â âââ public-url-tests/ # Direct URL access tests
â âââ backup-access.json
â
âââ 05-auth-audit/
â âââ auth-settings.json # Auth configuration
â âââ signup-tests/
â â âââ open-signup.json # Signup availability
â â âââ weak-password.json # Weak password test
â â âââ rate-limit.json # Rate limiting test
â âââ enumeration-tests/
â âââ login-timing.json # Timing attack data
â âââ recovery-timing.json
â âââ otp-enumeration.json
â
âââ 06-realtime-audit/
â âââ websocket-connection.json
â âââ postgres-changes/ # Table subscription tests
â â âââ users-streaming.json
â âââ broadcast-channels/ # Channel access tests
â â âââ admin-channel.json
â âââ presence-data/
â âââ exposed-users.json
â
âââ 07-functions-audit/
â âââ discovered-functions.json
â âââ function-tests/
â âââ hello-world.json
â âââ get-user-data-idor.json
â âââ admin-panel-escalation.json
â
âââ screenshots/ # Optional: browser screenshots
âââ ...
Usage
Initialize Evidence Directory
Initialize evidence collection for audit
Manual Evidence Save
Save evidence: [description] to [category]
Evidence File Format
Each evidence file follows this structure:
{
"evidence_id": "API-001",
"timestamp": "2025-01-31T10:30:00Z",
"category": "api-audit",
"type": "data-sample",
"finding_id": "P0-001",
"description": "Users table data accessible without authentication",
"request": {
"method": "GET",
"url": "https://abc123.supabase.co/rest/v1/users?select=*&limit=5",
"headers": {
"apikey": "[REDACTED - anon key]",
"Authorization": "Bearer [REDACTED - anon key]"
},
"curl_command": "curl -X GET 'https://abc123.supabase.co/rest/v1/users?select=*&limit=5' -H 'apikey: eyJ...' -H 'Authorization: Bearer eyJ...'"
},
"response": {
"status": 200,
"headers": {
"content-type": "application/json",
"x-total-count": "1247"
},
"body": [
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"email": "[REDACTED]@example.com",
"name": "[REDACTED]",
"created_at": "2025-01-15T10:30:00Z"
}
],
"body_redacted": true,
"total_rows_indicated": 1247
},
"analysis": {
"severity": "P0",
"impact": "All user PII accessible without authentication",
"affected_data": ["email", "name", "id"],
"row_count": 1247
}
}
Curl Commands File
All curl commands are collected in curl-commands.sh:
#!/bin/bash
# Supabase Security Audit - Reproducible Commands
# Target: https://myapp.example.com
# Project: abc123def.supabase.co
# Date: 2025-01-31
#
# IMPORTANT: Replace [ANON_KEY] with actual key before running
# WARNING: These commands may modify data - use with caution
SUPABASE_URL="https://abc123def.supabase.co"
ANON_KEY="eyJ..."
# === DETECTION ===
# Check if Supabase is used
curl -s "$SUPABASE_URL/rest/v1/" -H "apikey: $ANON_KEY" | head -100
# === TABLE LISTING ===
# Get OpenAPI schema (list all tables)
curl -s "$SUPABASE_URL/rest/v1/" -H "apikey: $ANON_KEY"
# === DATA ACCESS TESTS ===
# Test: Users table (P0 - should be blocked)
curl -s "$SUPABASE_URL/rest/v1/users?select=*&limit=5" \
-H "apikey: $ANON_KEY" \
-H "Authorization: Bearer $ANON_KEY"
# Test: Orders table (should be blocked by RLS)
curl -s "$SUPABASE_URL/rest/v1/orders?select=*&limit=5" \
-H "apikey: $ANON_KEY" \
-H "Authorization: Bearer $ANON_KEY"
# === RLS BYPASS TESTS ===
# ... additional commands ...
Timeline File
The timeline.md provides chronological evidence:
# Audit Timeline
## 2025-01-31 10:00:00 - Audit Started
- Target: https://myapp.example.com
- Authorization confirmed
## 2025-01-31 10:05:00 - Detection Phase
- Supabase detected with high confidence
- Project URL: https://abc123def.supabase.co
- Evidence: `01-detection/initial-scan.json`
## 2025-01-31 10:10:00 - P0 CRITICAL: Service Key Exposed
- Service role key found in client code
- Location: /static/js/admin.chunk.js:89
- Evidence: `02-extraction/service-key-exposure/`
## 2025-01-31 10:15:00 - API Audit Started
- 8 tables discovered
- Evidence: `03-api-audit/tables/tables-list.json`
## 2025-01-31 10:20:00 - P0 CRITICAL: Users Table Exposed
- All 1,247 user records accessible
- PII exposed: email, name
- Evidence: `03-api-audit/data-samples/users-sample.json`
...
Context Output
Updates .sb-pentest-context.json:
{
"evidence": {
"directory": ".sb-pentest-evidence",
"initialized_at": "2025-01-31T10:00:00Z",
"files_count": 45,
"categories": {
"detection": 3,
"extraction": 5,
"api-audit": 15,
"storage-audit": 8,
"auth-audit": 7,
"realtime-audit": 4,
"functions-audit": 3
},
"critical_evidence": [
"02-extraction/service-key-exposure/",
"03-api-audit/data-samples/users-sample.json",
"04-storage-audit/buckets/backups/"
]
}
}
Evidence Collection Rules
What to Collect
| Category | Evidence Type | Example |
|---|---|---|
| Always | Raw API responses | JSON responses |
| Always | Curl commands | Reproducible commands |
| Always | Timestamps | When each test occurred |
| P0/P1 | Data samples (redacted) | Sample rows with PII masked |
| P0 | Full request/response | Complete HTTP exchange |
| Optional | Screenshots | Browser evidence |
Redaction Rules
Sensitive data MUST be redacted in evidence files:
{
"original": "john.doe@example.com",
"redacted": "[REDACTED]@example.com"
}
{
"original": "John Doe",
"redacted": "[REDACTED]"
}
{
"original": "sk_live_xxxxxxxxxxxxxxxxxxxx",
"redacted": "sk_live_[REDACTED]"
}
NEVER store in evidence:
- Actual passwords
- Full credit card numbers
- Full API keys (show first/last 4 chars only)
- Full personal data (partial redaction required)
Naming Conventions
[category]-[test-name]-[timestamp].json
Examples:
users-anon-access-20250131-103000.jsonadmin-function-no-auth-20250131-143000.json
MANDATORY: Evidence File Updates
â ï¸ Evidence MUST be saved PROGRESSIVELY during execution.
Critical Rule: Save As You Go
DO NOT batch all evidence at the end. Instead:
- Before each test â Create evidence file placeholder
- After each request â Save request details immediately
- After each response â Save response immediately
- After analysis â Add analysis to evidence file
Directory Initialization
At audit start, create:
mkdir -p .sb-pentest-evidence/{01-detection,02-extraction,03-api-audit/tables,03-api-audit/data-samples,03-api-audit/rls-tests,03-api-audit/rpc-tests,04-storage-audit/buckets,04-storage-audit/public-url-tests,05-auth-audit/signup-tests,05-auth-audit/enumeration-tests,06-realtime-audit/postgres-changes,06-realtime-audit/broadcast-channels,07-functions-audit/function-tests,screenshots}
Log to Audit Log
[TIMESTAMP] [supabase-evidence] [START] Initializing evidence directory
[TIMESTAMP] [supabase-evidence] [CREATED] .sb-pentest-evidence/
[TIMESTAMP] [supabase-evidence] [CONTEXT_UPDATED] Evidence tracking initialized
Integration with Other Skills
This skill is automatically invoked by supabase-pentest. Each audit skill should:
- Save evidence to the appropriate subdirectory
- Use consistent naming conventions
- Add entries to
curl-commands.sh - Update
timeline.mdfor significant findings
Related Skills
supabase-pentestâ Orchestrator that initializes evidence collectionsupabase-reportâ Uses evidence for comprehensive reporting- All audit skills â Contribute evidence to their respective directories