supabase-audit-buckets-public
Identify storage buckets that are publicly accessible and may contain sensitive data.
Works with
Claude CodeCursorCodex CLIGitHub CopilotGemini CLI
---
name: supabase-audit-buckets-public
description: Identify storage buckets that are publicly accessible and may contain sensitive data.
license: MIT
---
# 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
1. **Development mistake** β Bucket set public during development
2. **Wrong bucket** β Sensitive file uploaded to public bucket
3. **Legacy** β Bucket was public before RLS existed
4. **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
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1. 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:
```sql
-- 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 π¨
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1. MAKE BUCKET PRIVATE NOW:
```sql
UPDATE storage.buckets
SET public = false
WHERE name = 'backups';
```
2. DELETE PUBLIC FILES:
Delete or move all sensitive files from public access
3. ROTATE ALL EXPOSED SECRETS:
- Stripe API keys
- Database passwords
- JWT secrets
- Any other keys in exposed files
4. AUDIT ACCESS LOGS:
Check if files were accessed by unauthorized parties
5. 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
```sql
-- 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
```sql
-- Only allow admin to create buckets
REVOKE INSERT ON storage.buckets FROM authenticated;
REVOKE INSERT ON storage.buckets FROM anon;
```
### 3. File Upload Validation
```typescript
// 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:
1. **Before analyzing each bucket** β Log the action to `.sb-pentest-audit.log`
2. **After each misconfiguration found** β Immediately update `.sb-pentest-context.json`
3. **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)
1. **Update `.sb-pentest-context.json`** with results:
```json
{
"public_bucket_audit": {
"timestamp": "...",
"public_buckets": 3,
"findings": [ ... ]
}
}
```
2. **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
```
3. **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
```json
{
"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 reportMore AI & ML skills
writing-shape
mattpocock/skills
Writing, exploit: shape raw material into an article, paragraph by paragraph.
275.5k
writing-fragments
mattpocock/skills
Writing, explore: mine raw fragments, no structure yet.
275.3k
full-output-enforcement
leonxlnx/taste-skill
Overrides default LLM truncation behavior. Enforces complete code generation, bans placeholder patterns, and handles token-limit splits cleanly. Apply to any task requiring exhaustive, unabridged output.
273.1k

