supabase-audit-buckets-list
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseList Storage Buckets
列出存储桶
🔴 CRITICAL: PROGRESSIVE FILE UPDATES REQUIREDYou MUST write to context files AS YOU GO, not just at the end.
- Write to
IMMEDIATELY after each bucket discovered.sb-pentest-context.json- Log to
BEFORE and AFTER each operation.sb-pentest-audit.log- 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 discovers all storage buckets configured in a Supabase project.
🔴 CRITICAL:需要逐步更新文件你必须逐步写入上下文文件,而不是只在最后一次性写入。
- 发现每个存储桶后立即写入
.sb-pentest-context.json- 在每个操作之前和之后记录到
.sb-pentest-audit.log- 不要等到技能完成后才更新文件
- 如果技能崩溃或被中断,所有之前的发现必须已保存
这不是可选要求。不逐步写入属于严重错误。
本技能可发现Supabase项目中配置的所有存储桶。
When to Use This Skill
何时使用本技能
- To inventory all storage buckets
- Before testing bucket access permissions
- To identify publicly accessible buckets
- As part of storage security audit
- 清点所有存储桶
- 测试存储桶访问权限之前
- 识别可公开访问的存储桶
- 作为存储安全审计的一部分
Prerequisites
前提条件
- Supabase URL and anon key available
- Detection completed
- 已获取Supabase URL和anon密钥
- 已完成检测
Understanding Supabase Storage
了解Supabase Storage
Supabase Storage provides:
https://[project].supabase.co/storage/v1/Buckets can be:
- Public: Files accessible without authentication
- Private: Files require authentication and RLS policies
Supabase Storage 提供:
https://[project].supabase.co/storage/v1/存储桶分为:
- 公开(Public):无需身份验证即可访问文件
- 私有(Private):文件需要身份验证和RLS策略
Storage API Endpoints
Storage API 端点
| Endpoint | Purpose |
|---|---|
| List buckets |
| List files in bucket |
| Access file |
| Public file URL |
| 端点 | 用途 |
|---|---|
| 列出存储桶 |
| 列出存储桶中的文件 |
| 访问文件 |
| 公开文件URL |
Usage
使用方法
Basic Bucket List
基础存储桶列表
List storage buckets on my Supabase project列出我的Supabase项目中的存储桶With Configuration Details
包含配置详情
List all buckets with their security settings列出所有存储桶及其安全设置Output Format
输出格式
═══════════════════════════════════════════════════════════
STORAGE BUCKETS
═══════════════════════════════════════════════════════════
Project: abc123def.supabase.co
Buckets Found: 5
─────────────────────────────────────────────────────────
Bucket Inventory
─────────────────────────────────────────────────────────
1. avatars
├── Public: ✅ YES
├── File Size Limit: 1MB
├── Allowed MIME: image/jpeg, image/png, image/webp
├── Files (estimated): 1,247
└── Status: ℹ️ Expected public bucket
Public URLs pattern:
https://abc123def.supabase.co/storage/v1/object/public/avatars/[filename]
2. documents
├── Public: ❌ NO (Private)
├── File Size Limit: 50MB
├── Allowed MIME: application/pdf, application/msword, *
├── Files (estimated): 523
└── Status: ✅ Private, needs RLS verification
3. uploads
├── Public: ✅ YES
├── File Size Limit: 100MB
├── Allowed MIME: */* (ANY)
├── Files (estimated): 3,891
└── Status: 🟠 P1 - Public with unrestricted MIME types
Risk: Any file type can be uploaded and accessed
Recommendation: Restrict allowed MIME types
4. backups
├── Public: ✅ YES ← UNEXPECTED
├── File Size Limit: 500MB
├── Allowed MIME: */*
├── Files (estimated): 45
└── Status: 🔴 P0 - Sensitive bucket is PUBLIC
Risk: Backup files publicly accessible!
Immediate Action: Change to private bucket
5. temp
├── Public: ❌ NO
├── File Size Limit: 10MB
├── Allowed MIME: */*
├── Files (estimated): 12
└── Status: ✅ Private temporary storage
─────────────────────────────────────────────────────────
Summary
─────────────────────────────────────────────────────────
Total Buckets: 5
Public Buckets: 3
├── Expected Public: 1 (avatars)
├── P1 Issues: 1 (uploads - unrestricted MIME)
└── P0 Critical: 1 (backups - should be private)
Private Buckets: 2
└── Need RLS verification with supabase-audit-buckets-read
Next Steps:
├── Fix 'backups' bucket - make private immediately
├── Restrict MIME types on 'uploads' bucket
├── Test RLS on private buckets
└── Verify no sensitive files in public buckets
══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
存储桶列表
═══════════════════════════════════════════════════════════
项目:abc123def.supabase.co
发现存储桶数量:5
─────────────────────────────────────────────────────────
存储桶清单
─────────────────────────────────────────────────────────
1. avatars
├── 公开:✅ 是
├── 文件大小限制:1MB
├── 允许的MIME类型:image/jpeg, image/png, image/webp
├── 文件数量(估算):1,247
└── 状态:ℹ️ 预期为公开存储桶
公开URL格式:
https://abc123def.supabase.co/storage/v1/object/public/avatars/[filename]
2. documents
├── 公开:❌ 否(私有)
├── 文件大小限制:50MB
├── 允许的MIME类型:application/pdf, application/msword, *
├── 文件数量(估算):523
└── 状态:✅ 私有,需要验证RLS
3. uploads
├── 公开:✅ 是
├── 文件大小限制:100MB
├── 允许的MIME类型:*/*(任意类型)
├── 文件数量(估算):3,891
└── 状态:🟠 P1 - 公开且MIME类型无限制
风险:可上传并访问任意类型的文件
建议:限制允许的MIME类型
4. backups
├── 公开:✅ 是 ← 不符合预期
├── 文件大小限制:500MB
├── 允许的MIME类型:*/*
├── 文件数量(估算):45
└── 状态:🔴 P0 - 敏感存储桶设为公开
风险:备份文件可公开访问!
立即行动:将存储桶改为私有
5. temp
├── 公开:❌ 否
├── 文件大小限制:10MB
├── 允许的MIME类型:*/*
├── 文件数量(估算):12
└── 状态:✅ 私有临时存储
─────────────────────────────────────────────────────────
摘要
─────────────────────────────────────────────────────────
总存储桶数:5
公开存储桶数:3
├── 预期公开:1个(avatars)
├── P1问题:1个(uploads - MIME类型无限制)
└── P0严重问题:1个(backups - 应设为私有)
私有存储桶数:2
└── 需要使用supabase-audit-buckets-read验证RLS
下一步:
├── 修复'backups'存储桶 - 立即设为私有
├── 限制'uploads'存储桶的MIME类型
├── 测试私有存储桶的RLS
└── 验证公开存储桶中无敏感文件
═══════════════════════════════════════════════════════════Bucket Configuration Analysis
存储桶配置分析
| Config | Good | Bad |
|---|---|---|
| public: false | ✅ Private by default | ❌ public: true for sensitive data |
| fileSizeLimit | ✅ Appropriate limits | ❌ No limit or very large |
| allowedMimeTypes | ✅ Restricted list | ❌ |
| 配置 | 合理 | 不合理 |
|---|---|---|
| public: false | ✅ 默认私有 | ❌ 敏感数据设为public: true |
| fileSizeLimit | ✅ 适当限制 | ❌ 无限制或限制过大 |
| allowedMimeTypes | ✅ 限制列表 | ❌ |
Context Output
上下文输出
json
{
"storage": {
"buckets": [
{
"name": "avatars",
"public": true,
"file_size_limit": 1048576,
"allowed_mime_types": ["image/jpeg", "image/png", "image/webp"],
"estimated_files": 1247,
"risk_level": "info",
"expected_public": true
},
{
"name": "backups",
"public": true,
"file_size_limit": 524288000,
"allowed_mime_types": ["*/*"],
"estimated_files": 45,
"risk_level": "P0",
"finding": "Sensitive bucket publicly accessible"
}
],
"summary": {
"total": 5,
"public": 3,
"private": 2,
"p0_issues": 1,
"p1_issues": 1
}
}
}json
{
"storage": {
"buckets": [
{
"name": "avatars",
"public": true,
"file_size_limit": 1048576,
"allowed_mime_types": ["image/jpeg", "image/png", "image/webp"],
"estimated_files": 1247,
"risk_level": "info",
"expected_public": true
},
{
"name": "backups",
"public": true,
"file_size_limit": 524288000,
"allowed_mime_types": ["*/*"],
"estimated_files": 45,
"risk_level": "P0",
"finding": "Sensitive bucket publicly accessible"
}
],
"summary": {
"total": 5,
"public": 3,
"private": 2,
"p0_issues": 1,
"p1_issues": 1
}
}
}Security Recommendations
安全建议
For Public Buckets
针对公开存储桶
sql
-- Create restrictive RLS policy even for public buckets
CREATE POLICY "Public read avatars"
ON storage.objects FOR SELECT
USING (bucket_id = 'avatars');
CREATE POLICY "Users upload own avatar"
ON storage.objects FOR INSERT
WITH CHECK (
bucket_id = 'avatars'
AND auth.uid()::text = (storage.foldername(name))[1]
);sql
-- 即使是公开存储桶也要创建严格的RLS策略
CREATE POLICY "Public read avatars"
ON storage.objects FOR SELECT
USING (bucket_id = 'avatars');
CREATE POLICY "Users upload own avatar"
ON storage.objects FOR INSERT
WITH CHECK (
bucket_id = 'avatars'
AND auth.uid()::text = (storage.foldername(name))[1]
);For Private Buckets
针对私有存储桶
sql
-- Only owners can access their files
CREATE POLICY "Users access own documents"
ON storage.objects FOR ALL
USING (
bucket_id = 'documents'
AND auth.uid()::text = (storage.foldername(name))[1]
);sql
-- 仅所有者可访问自己的文件
CREATE POLICY "Users access own documents"
ON storage.objects FOR ALL
USING (
bucket_id = 'documents'
AND auth.uid()::text = (storage.foldername(name))[1]
);Fix Public Backup Bucket
修复公开的备份存储桶
sql
-- Make bucket private
UPDATE storage.buckets
SET public = false
WHERE name = 'backups';
-- Add strict RLS
CREATE POLICY "Only admins access backups"
ON storage.objects FOR ALL
USING (
bucket_id = 'backups'
AND (SELECT is_admin FROM profiles WHERE id = auth.uid())
);sql
-- 将存储桶设为私有
UPDATE storage.buckets
SET public = false
WHERE name = 'backups';
-- 添加严格的RLS
CREATE POLICY "Only admins access backups"
ON storage.objects FOR ALL
USING (
bucket_id = 'backups'
AND (SELECT is_admin FROM profiles WHERE id = auth.uid())
);Common Issues
常见问题
❌ Problem: Cannot list buckets
✅ Solution: Storage API may be restricted. This is actually good security. Note as "unable to enumerate."
❌ Problem: Many buckets found
✅ Solution: Large applications may have many. Focus on public buckets first.
❌ Problem: Bucket count doesn't match expected
✅ Solution: Some buckets may be created dynamically. Check application code.
❌ 问题:无法列出存储桶
✅ 解决方案: Storage API可能被限制,这实际上是良好的安全设置。记录为“无法枚举”即可。
❌ 问题:发现大量存储桶
✅ 解决方案: 大型应用可能有很多存储桶。优先关注公开存储桶。
❌ 问题:存储桶数量与预期不符
✅ 解决方案: 部分存储桶可能是动态创建的。检查应用代码。
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 starting bucket enumeration → Log the action to
.sb-pentest-audit.log - After each bucket discovered → Immediately update
.sb-pentest-context.json - After each configuration analyzed → Log the result
This ensures that if the skill is interrupted, crashes, or times out, all findings up to that point are preserved.
不要批量在最后写入。而是:
- 开始枚举存储桶之前 → 将操作记录到
.sb-pentest-audit.log - 发现每个存储桶后 → 立即更新
.sb-pentest-context.json - 分析每个配置后 → 记录结果
这样可以确保如果技能被中断、崩溃或超时,截至当时的所有发现都已保存。
Required Actions (Progressive)
必须执行的逐步操作
-
Updatewith results:
.sb-pentest-context.jsonjson{ "storage": { "buckets": [ ... ], "summary": { "total": 5, "public": 3, "private": 2 } } } -
Log to:
.sb-pentest-audit.log[TIMESTAMP] [supabase-audit-buckets-list] [START] Listing storage buckets [TIMESTAMP] [supabase-audit-buckets-list] [SUCCESS] Found 5 buckets [TIMESTAMP] [supabase-audit-buckets-list] [CONTEXT_UPDATED] .sb-pentest-context.json updated -
If files don't exist, create them before writing.
FAILURE TO UPDATE CONTEXT FILES IS NOT ACCEPTABLE.
-
更新保存结果:
.sb-pentest-context.jsonjson{ "storage": { "buckets": [ ... ], "summary": { "total": 5, "public": 3, "private": 2 } } } -
记录到:
.sb-pentest-audit.log[TIMESTAMP] [supabase-audit-buckets-list] [START] 列出存储桶 [TIMESTAMP] [supabase-audit-buckets-list] [SUCCESS] 发现5个存储桶 [TIMESTAMP] [supabase-audit-buckets-list] [CONTEXT_UPDATED] .sb-pentest-context.json已更新 -
如果文件不存在,在写入前创建它们。
不更新上下文文件是不允许的。
MANDATORY: Evidence Collection
强制要求:收集证据
📁 Evidence Directory:
.sb-pentest-evidence/04-storage-audit/📁 证据目录:
.sb-pentest-evidence/04-storage-audit/Evidence Files to Create
需要创建的证据文件
| File | Content |
|---|---|
| All bucket configurations |
| File listing per bucket |
| 文件 | 内容 |
|---|---|
| 所有存储桶配置 |
| 每个存储桶的文件列表 |
Evidence Format
证据格式
json
{
"evidence_id": "STG-LIST-001",
"timestamp": "2025-01-31T10:35:00Z",
"category": "storage-audit",
"type": "bucket_enumeration",
"request": {
"method": "GET",
"url": "https://abc123def.supabase.co/storage/v1/bucket",
"curl_command": "curl -s '$URL/storage/v1/bucket' -H 'apikey: $ANON_KEY' -H 'Authorization: Bearer $ANON_KEY'"
},
"buckets": [
{
"name": "avatars",
"public": true,
"file_size_limit": 1048576,
"allowed_mime_types": ["image/jpeg", "image/png"],
"risk_level": "info",
"assessment": "Appropriate for public avatars"
},
{
"name": "backups",
"public": true,
"file_size_limit": 524288000,
"allowed_mime_types": ["*/*"],
"risk_level": "P0",
"assessment": "CRITICAL: Backup bucket should not be public"
}
],
"summary": {
"total_buckets": 5,
"public_buckets": 3,
"private_buckets": 2,
"critical_misconfigurations": 1
}
}json
{
"evidence_id": "STG-LIST-001",
"timestamp": "2025-01-31T10:35:00Z",
"category": "storage-audit",
"type": "bucket_enumeration",
"request": {
"method": "GET",
"url": "https://abc123def.supabase.co/storage/v1/bucket",
"curl_command": "curl -s '$URL/storage/v1/bucket' -H 'apikey: $ANON_KEY' -H 'Authorization: Bearer $ANON_KEY'"
},
"buckets": [
{
"name": "avatars",
"public": true,
"file_size_limit": 1048576,
"allowed_mime_types": ["image/jpeg", "image/png"],
"risk_level": "info",
"assessment": "适合作为公开头像存储桶"
},
{
"name": "backups",
"public": true,
"file_size_limit": 524288000,
"allowed_mime_types": ["*/*"],
"risk_level": "P0",
"assessment": "CRITICAL: 备份存储桶不应设为公开"
}
],
"summary": {
"total_buckets": 5,
"public_buckets": 3,
"private_buckets": 2,
"critical_misconfigurations": 1
}
}Add to curl-commands.sh
添加到curl-commands.sh
bash
undefinedbash
undefined=== STORAGE BUCKET ENUMERATION ===
=== 存储桶枚举 ===
List all buckets
列出所有存储桶
curl -s "$SUPABASE_URL/storage/v1/bucket"
-H "apikey: $ANON_KEY"
-H "Authorization: Bearer $ANON_KEY"
-H "apikey: $ANON_KEY"
-H "Authorization: Bearer $ANON_KEY"
curl -s "$SUPABASE_URL/storage/v1/bucket"
-H "apikey: $ANON_KEY"
-H "Authorization: Bearer $ANON_KEY"
-H "apikey: $ANON_KEY"
-H "Authorization: Bearer $ANON_KEY"
List files in specific bucket
列出指定存储桶中的文件
curl -s "$SUPABASE_URL/storage/v1/object/list/backups"
-H "apikey: $ANON_KEY"
-H "Authorization: Bearer $ANON_KEY"
-H "apikey: $ANON_KEY"
-H "Authorization: Bearer $ANON_KEY"
undefinedcurl -s "$SUPABASE_URL/storage/v1/object/list/backups"
-H "apikey: $ANON_KEY"
-H "Authorization: Bearer $ANON_KEY"
-H "apikey: $ANON_KEY"
-H "Authorization: Bearer $ANON_KEY"
undefinedRelated Skills
相关技能
- — Attempt to read files
supabase-audit-buckets-read - — Find misconfigured public buckets
supabase-audit-buckets-public - — Test storage RLS policies
supabase-audit-storage-rls
- — 尝试读取文件
supabase-audit-buckets-read - — 查找配置错误的公开存储桶
supabase-audit-buckets-public - — 测试存储RLS策略
supabase-audit-storage-rls