Public Bucket Audit
π΄ 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 bucket analyzed
-
Log to .sb-pentest-audit.log BEFORE and AFTER each 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 specifically focuses on identifying misconfigured public buckets and exposed sensitive content.
When to Use This Skill
-
Quick check for public bucket misconfigurations
-
When you suspect sensitive data in public storage
-
As a focused security check for storage
-
Before deploying to production
Prerequisites
- Supabase URL and anon key available
Why Public Buckets Are Risky
Public buckets allow:
Access Type Description
Direct URL Anyone with the URL can download
Enumeration File listing may be possible
No Auth No authentication required
Caching CDN may cache sensitive files
Common Misconfiguration Scenarios
-
Development mistake β Bucket set public during development
-
Wrong bucket β Sensitive file uploaded to public bucket
-
Legacy β Bucket was public before RLS existed
-
Intentional but wrong β Assumed "nobody knows the URL"
Usage
Quick Public Bucket Check
Check for misconfigured public buckets
Deep Scan
Deep scan public buckets for sensitive content
Output Format
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ PUBLIC BUCKET SECURITY AUDIT βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Project: abc123def.supabase.co
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Public Bucket Discovery βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Public Buckets Found: 3/5
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- avatars β APPROPRIATE βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Status: Public (Expected) Purpose: User profile pictures Content Analysis: βββ All files are images (jpg, png, webp) βββ No sensitive filenames detected βββ File sizes appropriate for avatars (< 1MB) βββ No metadata concerns
Assessment: This bucket appropriately contains only public user-facing content.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ 2. uploads π P1 - NEEDS REVIEW βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Status: Public (Unexpected for this content) Purpose: User file uploads
Content Analysis: βββ Mixed file types (PDF, DOC, images) βββ Some sensitive filenames detected βββ Should likely be private with RLS
Sensitive Content Indicators: βββ 12 files with 'invoice' in name βββ 8 files with 'contract' in name βββ 3 files with 'passport' in name βββ 156 PDF files (may contain sensitive data)
Risk Assessment: βββ π User-uploaded content publicly accessible Anyone with filename can access any user's files
Recommendation:
-- Make bucket private
UPDATE storage.buckets
SET public = false
WHERE name = 'uploads';
-- Add user-specific RLS
CREATE POLICY "Users access own uploads"
ON storage.objects FOR ALL
USING (
bucket_id = 'uploads'
AND auth.uid()::text = (storage.foldername(name))[1]
);
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
3. backups π΄ P0 - CRITICAL MISCONFIGURATION
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Status: Public (SHOULD NEVER BE PUBLIC)
Purpose: Database backups
β οΈ CRITICAL: Backup files publicly accessible!
Exposed Content:
βββ π΄ db-backup-2025-01-30.sql (125MB)
β βββ Full database dump with all user data
βββ π΄ db-backup-2025-01-29.sql (124MB)
β βββ Previous day backup
βββ π΄ users-export.csv (2.3MB)
β βββ User data export with emails, names
βββ π΄ secrets.env (1KB)
β βββ Contains API keys and passwords!
βββ π΄ .env.production (1KB)
βββ Production environment secrets!
Public URLs (Currently Accessible):
https://abc123def.supabase.co/storage/v1/object/public/backups/db-backup-2025-01-30.sql
https://abc123def.supabase.co/storage/v1/object/public/backups/secrets.env
Impact:
βββ Complete database can be downloaded
βββ All user PII exposed
βββ All API secrets exposed
βββ Full application compromise possible
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π¨ IMMEDIATE ACTION REQUIRED π¨
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-
MAKE BUCKET PRIVATE NOW:
UPDATE storage.buckets
SET public = false
WHERE name = 'backups';
-
DELETE PUBLIC FILES:
Delete or move all sensitive files from public access
-
ROTATE ALL EXPOSED SECRETS:
- Stripe API keys
- Database passwords
- JWT secrets
- Any other keys in exposed files
-
AUDIT ACCESS LOGS:
Check if files were accessed by unauthorized parties
-
INCIDENT RESPONSE:
Consider this a data breach and follow your
incident response procedures
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Summary
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Public Buckets: 3
βββ β
Appropriate: 1 (avatars)
βββ π P1 Review: 1 (uploads)
βββ π΄ P0 Critical: 1 (backups)
Exposed Sensitive Files: 47
Exposed Secret Files: 2
Critical Finding: Database backups and secrets
publicly accessible via direct URL
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
## Bucket Classification
The skill classifies buckets by content:
| Classification | Criteria | Action |
|----------------|----------|--------|
| **Appropriate Public** | Profile images, public assets | None needed |
| **Needs Review** | User uploads, mixed content | Consider making private |
| **Critical Misconfiguration** | Backups, secrets, exports | Immediate remediation |
## Sensitive Content Patterns
### P0 - Critical (Never Public)
- `*.sql` - Database dumps
- `*.env*` - Environment files
- `*secret*`, `*credential*` - Secrets
- `*backup*` - Backup files
- `*export*` - Data exports
### P1 - High (Usually Private)
- `*invoice*`, `*payment*` - Financial
- `*contract*`, `*agreement*` - Legal
- `*passport*`, `*id*`, `*license*` - Identity
- User-uploaded documents
### P2 - Medium (Review Needed)
- Configuration files
- Log files
- Debug exports
## Context Output
```json
{
"public_bucket_audit": {
"timestamp": "2025-01-31T12:00:00Z",
"public_buckets": 3,
"findings": [
{
"bucket": "backups",
"severity": "P0",
"issue": "Database backups and secrets publicly accessible",
"exposed_files": 45,
"critical_files": [
"db-backup-2025-01-30.sql",
"secrets.env",
".env.production"
],
"remediation": "Make bucket private immediately, rotate secrets"
}
]
}
}
Prevention Checklist
After fixing issues, implement these controls:
1. Default Private Buckets
-- Supabase creates buckets public by default in UI
-- Always verify and change to private if needed
UPDATE storage.buckets
SET public = false
WHERE name = 'new-bucket';
2. Restrict Bucket Creation
-- Only allow admin to create buckets
REVOKE INSERT ON storage.buckets FROM authenticated;
REVOKE INSERT ON storage.buckets FROM anon;
3. File Upload Validation
// Validate file type before upload
const allowedTypes = ['image/jpeg', 'image/png'];
if (!allowedTypes.includes(file.type)) {
throw new Error('Invalid file type');
}
// Use user-specific paths
const path = `${user.id}/${file.name}`;
await supabase.storage.from('uploads').upload(path, file);
4. Regular Audits
Run this skill regularly:
- Before each production deployment
- Weekly automated scans
- After any storage configuration changes
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 analyzing each bucket β Log the action to .sb-pentest-audit.log
- After each misconfiguration found β Immediately update .sb-pentest-context.json
- After each sensitive file detected β Log the finding immediately
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.json
with results:
{
"public_bucket_audit": {
"timestamp": "...",
"public_buckets": 3,
"findings": [ ... ]
}
}
-
Log to .sb-pentest-audit.log
:
[TIMESTAMP] [supabase-audit-buckets-public] [START] Auditing public buckets
[TIMESTAMP] [supabase-audit-buckets-public] [FINDING] P0: backups bucket is public
[TIMESTAMP] [supabase-audit-buckets-public] [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/04-storage-audit/public-url-tests/
Evidence Files to Create
File
Content
public-url-tests/[bucket]-access.json
Public URL access test results
public-url-tests/sensitive-content.json
Sensitive content found
Evidence Format
{
"evidence_id": "STG-PUB-001",
"timestamp": "2025-01-31T10:45:00Z",
"category": "storage-audit",
"type": "public_bucket_audit",
"severity": "P0",
"bucket": "backups",
"public_url_test": {
"url": "https://abc123def.supabase.co/storage/v1/object/public/backups/secrets.env",
"curl_command": "curl -I 'https://abc123def.supabase.co/storage/v1/object/public/backups/secrets.env'",
"response_status": 200,
"content_type": "text/plain",
"accessible": true
},
"assessment": {
"classification": "critical_misconfiguration",
"should_be_public": false,
"contains_sensitive_data": true,
"file_types_exposed": ["sql", "env", "csv"]
},
"remediation": {
"immediate": "UPDATE storage.buckets SET public = false WHERE name = 'backups';",
"secrets_to_rotate": ["All keys in secrets.env"],
"incident_response": "Consider this a data breach"
}
}
Related Skills
- supabase-audit-buckets-list
β List all buckets
- supabase-audit-buckets-read
β Test file access
- supabase-report
β Generate comprehensive report