关于 supabase-audit-buckets-list
用于 Supabase 安全审计的技能,可枚举项目中的 Storage 存储桶并检查其配置。适合在权限测试前盘点存储资源,并将结果逐步记录到上下文和审计文件。
主要功能
- 01枚举 Storage 存储桶
- 02查看公开状态和配置限制
- 03逐步保存审计上下文
- 04记录审计日志并收集证据
适用场景
- 01在权限测试前盘点存储桶
- 02查找可能公开的存储桶
- 03审查文件大小与 MIME 类型限制
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ yoanbernabeu/ supabase-pentest-skills --skill supabase-audit-buckets-list安装后在 Claude Code 中输入/supabase-audit-buckets-list确认已加载。
详细介绍
列出存储桶
🔴 严重:必须渐进式更新文件
你必须在操作过程中写入上下文文件,而不是只在最后写入。
- 每发现一个存储桶后,立即写入
.sb-pentest-context.json- 每次操作之前和之后都要记录到
.sb-pentest-audit.log- 不要等到技能执行完毕后才更新文件
- 如果技能崩溃或中断,之前的所有发现都必须已经保存
这不是可选要求。未能渐进式写入属于严重错误。
此技能用于发现 Supabase 项目中配置的所有存储桶。
何时使用此技能
- 清点所有存储桶
- 测试存储桶访问权限前
- 识别可公开访问的存储桶
- 作为存储安全审计的一部分
前置条件
- 已获取 Supabase URL 和 anon key
- 已完成检测
了解 Supabase Storage
Supabase Storage 提供:
https://[project].supabase.co/storage/v1/
存储桶可以是:
- 公开:无需身份验证即可访问文件
- 私有:访问文件需要身份验证和 RLS 策略
Storage API 端点
| 端点 | 用途 |
|---|---|
/storage/v1/bucket | 列出存储桶 |
/storage/v1/object/list/[bucket] | 列出存储桶中的文件 |
/storage/v1/object/[bucket]/[path] | 访问文件 |
/storage/v1/object/public/[bucket]/[path] | 公开文件 URL |
用法
基本存储桶列表
List storage buckets on my Supabase project
包含配置详情
List all buckets with their security settings
输出格式
═══════════════════════════════════════════════════════════
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
═══════════════════════════════════════════════════════════
存储桶配置分析
| 配置 | 良好 | 不佳 |
|---|---|---|
| public: false | ✅ 默认设为私有 | ❌ 敏感数据设为 public: true |
| fileSizeLimit | ✅ 限制合理 | ❌ 无限制或限制过大 |
| allowedMimeTypes | ✅ 限制类型列表 | ❌ */* 允许任何类型 |
上下文输出
{
"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
}
}
}
安全建议
针对公开存储桶
-- 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]
);
针对私有存储桶
-- 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]
);
修复公开备份存储桶
-- 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())
);
常见问题
❌ 问题: 无法列出存储桶 ✅ 解决方案: Storage API 可能受到限制。这实际上有利于安全。请记录为“无法枚举”。
❌ 问题: 发现大量存储桶 ✅ 解决方案: 大型应用可能有很多存储桶。请优先检查公开存储桶。
❌ 问题: 存储桶数量与预期不符 ✅ 解决方案: 某些存储桶可能是动态创建的。请检查应用代码。
必须:渐进式更新上下文文件
⚠️ 此技能必须在执行过程中渐进式更新跟踪文件,而不是只在最后更新。
重要规则:边做边写
不要等到最后才批量写入。请按以下步骤操作:
- 开始枚举存储桶之前 → 将操作记录到
.sb-pentest-audit.log - 每发现一个存储桶后 → 立即更新
.sb-pentest-context.json - 每分析完一项配置后 → 记录分析结果
这样可以确保即使技能被中断、崩溃或超时,此前的所有发现仍会得到保留。
必须执行的操作(渐进式)
-
更新
.sb-pentest-context.json,写入结果:{ "storage": { "buckets": [ ... ], "summary": { "total": 5, "public": 3, "private": 2 } } } -
记录到
.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 -
如果文件不存在,请在写入前创建文件。
不接受未更新上下文文件的情况。
必须:收集证据
📁 证据目录: .sb-pentest-evidence/04-storage-audit/
需要创建的证据文件
| 文件 | 内容 |
|---|---|
buckets-config.json | 所有存储桶配置 |
buckets/[name]/file-list.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
}
}
添加到 curl-commands.sh
# === STORAGE BUCKET ENUMERATION ===
# List all buckets
curl -s "$SUPABASE_URL/storage/v1/bucket" \
-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"
相关技能
supabase-audit-buckets-read— 尝试读取文件supabase-audit-buckets-public— 查找配置错误的公开存储桶supabase-audit-storage-rls— 测试存储 RLS 策略
评论
支持 Markdown