supabase-audit-buckets-read
Attempt to list and read files from storage buckets to verify access controls.
Works with
Claude CodeCursorCodex CLIGitHub CopilotGemini CLI
---
name: supabase-audit-buckets-read
description: Attempt to list and read files from storage buckets to verify access controls.
license: MIT
---
# 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.json` **IMMEDIATELY after each bucket tested**
> - Log to `.sb-pentest-audit.log` **BEFORE 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:
1. **List files** in each bucket
2. **Read file metadata**
3. **Download sample files** (for content type verification)
4. **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 buckets
```
### Specific Bucket
```
Test file access on the documents bucket
```
### List Only (No Download)
```
List accessible files without downloading content
```
## Output 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
```json
{
"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
```bash
# 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 secrets
```
### For Public Bucket Fix
```sql
-- 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
```sql
-- 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:
1. **Before testing each bucket** β Log the action to `.sb-pentest-audit.log`
2. **After each sensitive file found** β Immediately update `.sb-pentest-context.json`
3. **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)
1. **Update `.sb-pentest-context.json`** with results:
```json
{
"storage_access": {
"timestamp": "...",
"buckets_tested": 5,
"findings": [ ... ],
"summary": { "total_files_accessible": 5183, ... }
}
}
```
2. **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 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/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)
```json
{
"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
```bash
# === 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 -1000
```
## Related Skills
- `supabase-audit-buckets-list` β List buckets first
- `supabase-audit-buckets-public` β Focus on public access issues
- `supabase-report` β Generate full 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

