Attempt to list and read files from storage buckets to verify access controls.
Install
npx skillscat add yoanbernabeu/supabase-pentest-skills/supabase-audit-buckets-read Install via the SkillsCat registry.
Bucket File Access Test
๐ด 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 bucket tested- Log to
.sb-pentest-audit.logBEFORE and AFTER each file access test- 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 tests actual file access in storage buckets to verify permissions.
When to Use This Skill
- After listing buckets, to verify actual access
- To test storage RLS policy effectiveness
- To check for sensitive file exposure
- To document what files are accessible
Prerequisites
- Buckets listed (auto-invokes if needed)
- Anon key available
How It Works
The skill attempts to:
- List files in each bucket
- Read file metadata
- Download sample files (for content type verification)
- Check public URL access
Important: This is READ-ONLY. No files are modified or deleted.
Test Approach
| Bucket Type | Tests Performed |
|---|---|
| Public | Direct URL access, listing, metadata |
| Private | API listing with anon key, authenticated access |
Usage
Basic Read Test
Test read access on storage bucketsSpecific Bucket
Test file access on the documents bucketList Only (No Download)
List accessible files without downloading contentOutput Format
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
BUCKET FILE ACCESS TEST
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Project: abc123def.supabase.co
Buckets Tested: 5
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
avatars (Public Bucket)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Status: โ
Expected Access
Files Found: 1,247
Sample Files:
โโโ user-550e8400.jpg (45KB) - Public URL works
โโโ user-6ba7b810.png (32KB) - Public URL works
โโโ default.png (12KB) - Public URL works
Access Methods:
โโโ Public URL: โ
Accessible
โโโ API Listing: โ
Works
โโโ Metadata: โ
Visible
Assessment: Expected behavior for avatar storage.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
documents (Private Bucket)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Status: โ
PROPERLY PROTECTED
Files Found: 0 (via anon key)
Access Methods:
โโโ Public URL: โ 403 Forbidden (correct)
โโโ API Listing: โ Empty result (RLS working)
โโโ Metadata: โ Not accessible (correct)
Assessment: RLS policies working correctly.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
uploads (Public Bucket)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Status: ๐ P1 - SENSITIVE FILES EXPOSED
Files Found: 3,891
Sensitive Files Detected:
โโโ ๐ด invoice-2025-001.pdf - Contains financial data
โโโ ๐ด contract-signed.pdf - Legal document
โโโ ๐ด id-verification.jpg - Personal ID photo!
โโโ โ ๏ธ database-export.csv - Possible data export
โโโ โ ๏ธ config.json - Configuration file
File Types Distribution:
โโโ PDF: 1,234 (31%)
โโโ Images: 2,100 (54%)
โโโ Documents: 450 (12%)
โโโ Other: 107 (3%)
Assessment: Bucket contains sensitive files that should not be public!
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
backups (Public - CRITICAL)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Status: ๐ด P0 - CRITICAL DATA EXPOSURE
Files Found: 45
Exposed Files:
โโโ ๐ด db-backup-2025-01-30.sql (125MB) - DATABASE BACKUP!
โโโ ๐ด db-backup-2025-01-29.sql (124MB) - DATABASE BACKUP!
โโโ ๐ด users-export.csv (2.3MB) - USER DATA EXPORT!
โโโ ๐ด secrets.env (1KB) - ENVIRONMENT SECRETS!
โโโ ๐ด .env.production (1KB) - PRODUCTION SECRETS!
Sample Content (secrets.env):
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STRIPE_SECRET_KEY=sk_live_xxxxxxxxxxxx โ
โ DATABASE_URL=postgresql://postgres:xxx@... โ
โ JWT_SECRET=super-secret-jwt-key โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๏ธ IMMEDIATE ACTION REQUIRED:
1. Make bucket private NOW
2. Rotate ALL exposed secrets
3. Delete backup files from public access
4. Audit for unauthorized access in logs
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
temp (Private Bucket)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Status: โ
PROPERLY PROTECTED
Files Found: 0 (via anon key)
Assessment: Access correctly restricted.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
P0 Critical: 1 bucket (backups - DB dumps & secrets exposed)
P1 High: 1 bucket (uploads - sensitive documents in public bucket)
Protected: 2 buckets (documents, temp)
Expected: 1 bucket (avatars)
Total Files Accessible: 5,183
Sensitive Files Exposed: 52
Secret Files Exposed: 3
Immediate Actions:
1. ๐ด DELETE or make private 'backups' bucket
2. ๐ด Rotate Stripe key, DB password, JWT secret
3. ๐ Move sensitive files from 'uploads' to private bucket
4. Review all 52 sensitive files for exposure impact
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโSensitive File Detection
The skill identifies sensitive files by:
Filename Patterns
| Pattern | Risk | Type |
|---|---|---|
*.sql, backup* |
P0 | Database dumps |
.env*, *secrets* |
P0 | Secret files |
*password*, *credential* |
P0 | Credentials |
*invoice*, *payment* |
P1 | Financial |
*contract*, *agreement* |
P1 | Legal |
*id*, *passport*, *license* |
P1 | Identity |
*export*, *dump* |
P1 | Data exports |
Content Detection
For accessible files, the skill samples content for:
- API keys (patterns like
sk_live_,pk_test_) - Database credentials
- JWT secrets
- Personal information patterns
Context Output
{
"storage_access": {
"timestamp": "2025-01-31T11:30:00Z",
"buckets_tested": 5,
"findings": [
{
"bucket": "backups",
"severity": "P0",
"public": true,
"files_exposed": 45,
"sensitive_files": [
{
"path": "db-backup-2025-01-30.sql",
"size": 131072000,
"type": "database_backup",
"risk": "Full database accessible"
},
{
"path": "secrets.env",
"size": 1024,
"type": "secrets",
"exposed_secrets": ["STRIPE_SECRET_KEY", "DATABASE_URL", "JWT_SECRET"]
}
]
}
],
"summary": {
"total_files_accessible": 5183,
"sensitive_files": 52,
"secret_files": 3
}
}
}Remediation Steps
For Exposed Secrets
# 1. Rotate Stripe keys
# Stripe Dashboard โ Developers โ API Keys โ Roll Keys
# 2. Change database password
# Supabase Dashboard โ Settings โ Database โ Reset Password
# 3. Regenerate JWT secret
# Supabase Dashboard โ Settings โ API โ Regenerate JWT Secret
# 4. Update application environment variables
# Redeploy with new secretsFor Public Bucket Fix
-- Make bucket private
UPDATE storage.buckets
SET public = false
WHERE name = 'backups';
-- Delete sensitive files or move to secure location
DELETE FROM storage.objects
WHERE bucket_id = 'backups';For Upload Bucket
-- Add RLS to restrict access
CREATE POLICY "Users access own uploads"
ON storage.objects FOR ALL
USING (
bucket_id = 'uploads'
AND auth.uid()::text = (storage.foldername(name))[1]
);Common Issues
โ Problem: Cannot list files in private bucket
โ
Solution: This is correct behavior. RLS is working.
โ Problem: Large number of files to scan
โ
Solution: Use sampling mode for large buckets.
โ Problem: File download fails
โ
Solution: May be RLS restriction or network issue.
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 testing each bucket โ Log the action to
.sb-pentest-audit.log - After each sensitive file found โ Immediately update
.sb-pentest-context.json - After each bucket completed โ Log the summary
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 results:{ "storage_access": { "timestamp": "...", "buckets_tested": 5, "findings": [ ... ], "summary": { "total_files_accessible": 5183, ... } } }Log to
.sb-pentest-audit.log:[TIMESTAMP] [supabase-audit-buckets-read] [START] Testing bucket file access [TIMESTAMP] [supabase-audit-buckets-read] [FINDING] P0: backups bucket has exposed secrets [TIMESTAMP] [supabase-audit-buckets-read] [CONTEXT_UPDATED] .sb-pentest-context.json updatedIf files don't exist, create them before writing.
FAILURE TO UPDATE CONTEXT FILES IS NOT ACCEPTABLE.
MANDATORY: Evidence Collection
๐ Evidence Directory: .sb-pentest-evidence/04-storage-audit/buckets/
Evidence Files to Create
| File | Content |
|---|---|
buckets/[name]/file-list.json |
Files found in bucket |
buckets/[name]/sensitive-files.json |
Sensitive files detected |
buckets/[name]/sample-contents/ |
Redacted content samples |
Evidence Format (Sensitive Files Exposed)
{
"evidence_id": "STG-READ-001",
"timestamp": "2025-01-31T10:40:00Z",
"category": "storage-audit",
"type": "file_access",
"severity": "P0",
"bucket": "backups",
"public": true,
"files_found": 45,
"sensitive_files": [
{
"path": "db-backup-2025-01-30.sql",
"size": 131072000,
"type": "database_backup",
"public_url": "https://abc123def.supabase.co/storage/v1/object/public/backups/db-backup-2025-01-30.sql",
"curl_command": "curl -o backup.sql 'https://abc123def.supabase.co/storage/v1/object/public/backups/db-backup-2025-01-30.sql'"
},
{
"path": "secrets.env",
"size": 1024,
"type": "secrets_file",
"content_sample": "STRIPE_SECRET_KEY=sk_live_[REDACTED]\nDATABASE_URL=postgresql://[REDACTED]",
"exposed_secrets": ["STRIPE_SECRET_KEY", "DATABASE_URL", "JWT_SECRET"]
}
],
"impact": {
"data_breach": true,
"secrets_exposed": true,
"affected_records": "All database records",
"credentials_to_rotate": ["Stripe API key", "Database password", "JWT secret"]
}
}Add to curl-commands.sh
# === STORAGE FILE ACCESS TESTS ===
# List files in backups bucket
curl -s "$SUPABASE_URL/storage/v1/object/list/backups" \
-H "apikey: $ANON_KEY"
# Direct access to public file (P0 if accessible)
curl -I "https://abc123def.supabase.co/storage/v1/object/public/backups/secrets.env"
# Download exposed backup (for evidence - be careful with size)
# curl -o evidence-backup-sample.sql "https://abc123def.supabase.co/storage/v1/object/public/backups/db-backup-2025-01-30.sql" | head -1000Related Skills
supabase-audit-buckets-listโ List buckets firstsupabase-audit-buckets-publicโ Focus on public access issuessupabase-reportโ Generate full report