Skip to content
Back to skills

Supabase Audit Buckets Read

BSecurity

Attempt to list and read files from storage buckets to verify access controls.

  • 68 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added February 8, 2026
securitygobashsqltestingapidatabase

Works with

  • api

Security analysis

B88/100
  • criticalExfiltrates credentials via HTTP โ€” exact pattern from Snyk ToxicSkills study

Pro shows the line behind each finding and how to fix it

Scanned February 12, 2026

npx -y skills add yoanbernabeu/supabase-pentest-skills --skill supabase-audit-buckets-read --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Supabase Audit Buckets Read?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Supabase Audit Buckets Read
[![Security: B โ€” Skills Directory](https://www.skillsdirectory.com/api/skills/yoanbernabeu-supabase-audit-buckets-read/badge)](https://www.skillsdirectory.com/skills/yoanbernabeu-supabase-audit-buckets-read)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: supabase-audit-buckets-read
description: Attempt to list and read files from storage buckets to verify access controls.
---

# 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 report

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading commentsโ€ฆ

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.