supabase-audit-buckets-read

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

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.
🔴 严重警告:需逐步更新文件
你必须逐步写入上下文文件,而不是仅在最后统一写入。
  • 测试完每个存储桶后,立即写入
    .sb-pentest-context.json
  • 在每次文件访问测试前后,都要记录到
    .sb-pentest-audit.log
  • 禁止等到技能完成后再批量更新文件
  • 如果技能崩溃或被中断,所有已发现的结果必须已保存
此要求为强制性规定,未逐步写入文件属于严重错误。
本技能通过测试存储桶的实际文件访问权限,来验证权限设置是否合规。

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
  • 列出存储桶后,验证实际访问权限
  • 测试存储RLS策略的有效性
  • 检查敏感文件是否暴露
  • 记录可访问的文件清单

Prerequisites

前置条件

  • Buckets listed (auto-invokes if needed)
  • Anon key available
  • 已列出存储桶(若未完成,将自动调用对应技能)
  • 拥有匿名密钥(anon key)

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.
本技能会尝试执行以下操作:
  1. 列出每个存储桶中的文件
  2. 读取文件元数据
  3. 下载样本文件(用于验证内容类型)
  4. 检查公开URL的可访问性
重要提示: 本技能仅执行只读操作,不会修改或删除任何文件。

Test Approach

测试方案

Bucket TypeTests Performed
PublicDirect URL access, listing, metadata
PrivateAPI listing with anon key, authenticated access
存储桶类型执行的测试内容
公开存储桶直接URL访问、文件列出、元数据读取
私有存储桶使用匿名密钥的API列出、已认证访问测试

Usage

使用方法

Basic Read Test

基础读取测试

Test read access on storage buckets
Test read access on storage buckets

Specific Bucket

指定存储桶测试

Test file access on the documents bucket
Test file access on the documents bucket

List Only (No Download)

仅列出文件(不下载)

List accessible files without downloading content
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

═══════════════════════════════════════════════════════════
═══════════════════════════════════════════════════════════
 存储桶文件访问测试
═══════════════════════════════════════════════════════════

 项目:abc123def.supabase.co
 已测试存储桶数量:5

 ─────────────────────────────────────────────────────────
 avatars(公开存储桶)
 ─────────────────────────────────────────────────────────

 状态:✅ 符合预期访问权限
 发现文件数量:1,247

 样本文件:
 ├── user-550e8400.jpg(45KB)- 公开URL可正常访问
 ├── user-6ba7b810.png(32KB)- 公开URL可正常访问
 └── default.png(12KB)- 公开URL可正常访问

 访问方式验证:
 ├── 公开URL:✅ 可访问
 ├── API列出:✅ 正常工作
 └── 元数据:✅ 可见

 评估:符合头像存储的预期行为。

 ─────────────────────────────────────────────────────────
 documents(私有存储桶)
 ─────────────────────────────────────────────────────────

 状态:✅ 已正确保护
 发现文件数量:0(通过匿名密钥)

 访问方式验证:
 ├── 公开URL:❌ 403 禁止访问(符合预期)
 ├── API列出:❌ 无返回结果(RLS策略生效)
 └── 元数据:❌ 不可访问(符合预期)

 评估:RLS策略正常工作。

 ─────────────────────────────────────────────────────────
 uploads(公开存储桶)
 ─────────────────────────────────────────────────────────

 状态:🟠 P1 - 敏感文件暴露
 发现文件数量:3,891

 检测到的敏感文件:
 ├── 🔴 invoice-2025-001.pdf - 包含财务数据
 ├── 🔴 contract-signed.pdf - 法律文档
 ├── 🔴 id-verification.jpg - 个人身份证件照片!
 ├── ⚠️ database-export.csv - 可能为数据导出文件
 └── ⚠️ config.json - 配置文件

 文件类型分布:
 ├── PDF:1,234(31%)
 ├── 图片:2,100(54%)
 ├── 文档:450(12%)
 └── 其他:107(3%)

 评估:该存储桶包含不应公开的敏感文件!

 ─────────────────────────────────────────────────────────
 backups(公开存储桶 - 严重风险)
 ─────────────────────────────────────────────────────────

 状态:🔴 P0 - 关键数据暴露
 发现文件数量:45

 暴露的文件:
 ├── 🔴 db-backup-2025-01-30.sql(125MB)- 数据库备份文件!
 ├── 🔴 db-backup-2025-01-29.sql(124MB)- 数据库备份文件!
 ├── 🔴 users-export.csv(2.3MB)- 用户数据导出文件!
 ├── 🔴 secrets.env(1KB)- 环境密钥文件!
 └── 🔴 .env.production(1KB)- 生产环境密钥文件!

 样本内容(secrets.env):
 ┌─────────────────────────────────────────────────────────┐
 │ STRIPE_SECRET_KEY=sk_live_xxxxxxxxxxxx                 │
 │ DATABASE_URL=postgresql://postgres:xxx@...             │
 │ JWT_SECRET=super-secret-jwt-key                        │
 └─────────────────────────────────────────────────────────┘

 ⚠️ 需立即采取行动:
 1. 立即将该存储桶设为私有
 2. 轮换所有已暴露的密钥
 3. 删除公开可访问的备份文件
 4. 审计日志中是否存在未授权访问记录

 ─────────────────────────────────────────────────────────
 temp(私有存储桶)
 ─────────────────────────────────────────────────────────

 状态:✅ 已正确保护
 发现文件数量:0(通过匿名密钥)
 评估:访问权限已正确限制。

 ─────────────────────────────────────────────────────────
 总结
 ─────────────────────────────────────────────────────────

 P0 关键风险:1个存储桶(backups - 数据库备份和密钥暴露)
 P1 高风险:1个存储桶(uploads - 敏感文档存于公开存储桶)
 已正确保护:2个存储桶(documents、temp)
 符合预期:1个存储桶(avatars)

 可访问文件总数:5,183
 暴露的敏感文件数量:52
 暴露的密钥文件数量:3

 立即执行的操作:
 1. 🔴 删除或设为私有 'backups' 存储桶
 2. 🔴 轮换Stripe密钥、数据库密码、JWT密钥
 3. 🟠 将uploads中的敏感文件移至私有存储桶
 4. 评估所有52个敏感文件的暴露影响

═══════════════════════════════════════════════════════════

Sensitive File Detection

敏感文件检测

The skill identifies sensitive files by:
本技能通过以下方式识别敏感文件:

Filename Patterns

文件名模式

PatternRiskType
*.sql
,
backup*
P0Database dumps
.env*
,
*secrets*
P0Secret files
*password*
,
*credential*
P0Credentials
*invoice*
,
*payment*
P1Financial
*contract*
,
*agreement*
P1Legal
*id*
,
*passport*
,
*license*
P1Identity
*export*
,
*dump*
P1Data exports
模式风险等级类型
*.sql
,
backup*
P0数据库备份
.env*
,
*secrets*
P0密钥文件
*password*
,
*credential*
P0凭证文件
*invoice*
,
*payment*
P1财务文件
*contract*
,
*agreement*
P1法律文件
*id*
,
*passport*
,
*license*
P1身份证件
*export*
,
*dump*
P1数据导出文件

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
对于可访问的文件,本技能会抽样检测以下内容:
  • API密钥(如
    sk_live_
    pk_test_
    等模式)
  • 数据库凭证
  • JWT密钥
  • 个人信息模式

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
    }
  }
}
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
undefined
bash
undefined

1. Rotate Stripe keys

1. 轮换Stripe密钥

Stripe Dashboard → Developers → API Keys → Roll Keys

Stripe Dashboard → Developers → API Keys → Roll Keys

2. Change database password

2. 修改数据库密码

Supabase Dashboard → Settings → Database → Reset Password

Supabase Dashboard → Settings → Database → Reset Password

3. Regenerate JWT secret

3. 重新生成JWT密钥

Supabase Dashboard → Settings → API → Regenerate JWT Secret

Supabase Dashboard → Settings → API → Regenerate JWT Secret

4. Update application environment variables

4. 更新应用程序环境变量

Redeploy with new secrets

使用新密钥重新部署

undefined
undefined

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';
sql
-- 将存储桶设为私有
UPDATE storage.buckets
SET public = false
WHERE name = 'backups';

-- 删除敏感文件或移至安全位置
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]
  );
sql
-- 添加RLS策略限制访问
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.
问题:无法列出私有存储桶中的文件解决方案:这是正确行为,RLS策略已生效。
问题:需要扫描的文件数量过多解决方案:对大型存储桶使用抽样模式。
问题:文件下载失败解决方案:可能是RLS限制或网络问题导致。

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.
禁止在最后批量写入。应执行以下操作:
  1. 测试每个存储桶前 → 将操作记录到
    .sb-pentest-audit.log
  2. 发现每个敏感文件后 → 立即更新
    .sb-pentest-context.json
  3. 每个存储桶测试完成后 → 记录总结信息
这样可确保如果技能被中断、崩溃或超时,所有已完成的测试结果都已保存。

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.
  1. 更新
    .sb-pentest-context.json
    以保存结果:
    json
    {
      "storage_access": {
        "timestamp": "...",
        "buckets_tested": 5,
        "findings": [ ... ],
        "summary": { "total_files_accessible": 5183, ... }
      }
    }
  2. 记录到
    .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. 若文件不存在,在写入前先创建。
未更新上下文文件属于违规行为。

MANDATORY: Evidence Collection

强制性要求:证据收集

📁 Evidence Directory:
.sb-pentest-evidence/04-storage-audit/buckets/
📁 证据目录:
.sb-pentest-evidence/04-storage-audit/buckets/

Evidence Files to Create

需要创建的证据文件

FileContent
buckets/[name]/file-list.json
Files found in bucket
buckets/[name]/sensitive-files.json
Sensitive files detected
buckets/[name]/sample-contents/
Redacted content samples
文件内容
buckets/[name]/file-list.json
存储桶中发现的文件列表
buckets/[name]/sensitive-files.json
检测到的敏感文件列表
buckets/[name]/sample-contents/
已脱敏的内容样本

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"]
  }
}
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

添加到 curl-commands.sh

bash
undefined
bash
undefined

=== STORAGE FILE ACCESS TESTS ===

=== STORAGE FILE ACCESS TESTS ===

List files in backups bucket

List files in backups bucket

curl -s "$SUPABASE_URL/storage/v1/object/list/backups"
-H "apikey: $ANON_KEY"
curl -s "$SUPABASE_URL/storage/v1/object/list/backups"
-H "apikey: $ANON_KEY"

Direct access to public file (P0 if accessible)

Direct access to public file (P0 if accessible)

Download exposed backup (for evidence - be careful with size)

Download exposed backup (for evidence - be careful with size)

undefined
undefined

Related Skills

相关技能

  • supabase-audit-buckets-list
    — List buckets first
  • supabase-audit-buckets-public
    — Focus on public access issues
  • supabase-report
    — Generate full report
  • supabase-audit-buckets-list
    — 先列出存储桶
  • supabase-audit-buckets-public
    — 专注于公开访问问题
  • supabase-report
    — 生成完整报告