supabase-audit-buckets-list by yoanbernabeu/supabase-pentest-skills
npx skills add https://github.com/yoanbernabeu/supabase-pentest-skills --skill supabase-audit-buckets-list🔴 关键:必须进行渐进式文件更新
你必须在操作过程中就写入上下文文件,而不仅仅是在最后。
- 每次发现存储桶后,立即写入
.sb-pentest-context.json- 每次操作前后,记录到
.sb-pentest-audit.log- 不要等到技能执行完毕才更新文件
- 如果技能崩溃或被中断,所有之前的发现必须已经保存
这不是可选项。不进行渐进式写入是严重错误。
此技能用于发现 Supabase 项目中配置的所有存储桶。
Supabase 存储提供:
https://[project].supabase.co/storage/v1/
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
存储桶可以是:
| 端点 | 用途 |
|---|---|
/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
═══════════════════════════════════════════════════════════
存储桶
═══════════════════════════════════════════════════════════
项目: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
└── 验证公开存储桶中没有敏感文件
═══════════════════════════════════════════════════════════
| 配置 | 良好 | 不良 |
|---|---|---|
| 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
}
}
}
-- 即使对于公开存储桶,也要创建限制性 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]
);
-- 仅所有者可以访问其文件
CREATE POLICY "Users access own documents"
ON storage.objects FOR ALL
USING (
bucket_id = 'documents'
AND auth.uid()::text = (storage.foldername(name))[1]
);
-- 将存储桶设为私有
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())
);
❌ 问题: 无法列出存储桶 ✅ 解决方案: 存储 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 -s "$SUPABASE_URL/storage/v1/bucket" \
-H "apikey: $ANON_KEY" \
-H "Authorization: Bearer $ANON_KEY"
# 列出特定存储桶中的文件
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 策略每周安装次数
87
仓库
GitHub 星标数
32
首次出现时间
Jan 31, 2026
安全审计
安装于
claude-code70
codex64
opencode62
gemini-cli59
github-copilot54
cursor54
🔴 CRITICAL: PROGRESSIVE FILE UPDATES REQUIRED
You MUST write to context files AS YOU GO , not just at the end.
- Write to
.sb-pentest-context.jsonIMMEDIATELY after each bucket discovered- Log to
.sb-pentest-audit.logBEFORE and AFTER each operation- 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.
Supabase Storage provides:
https://[project].supabase.co/storage/v1/
Buckets can be:
| Endpoint | Purpose |
|---|---|
/storage/v1/bucket | List buckets |
/storage/v1/object/list/[bucket] | List files in bucket |
/storage/v1/object/[bucket]/[path] | Access file |
/storage/v1/object/public/[bucket]/[path] | Public file 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
═══════════════════════════════════════════════════════════
| Config | Good | Bad |
|---|---|---|
| public: false | ✅ Private by default | ❌ public: true for sensitive data |
| fileSizeLimit | ✅ Appropriate limits | ❌ No limit or very large |
| allowedMimeTypes | ✅ Restricted list | ❌ */* allows anything |
{
"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())
);
❌ 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.
⚠️ This skill MUST update tracking files PROGRESSIVELY during execution, NOT just at the end.
DO NOT batch all writes at the end. Instead:
.sb-pentest-audit.log.sb-pentest-context.jsonThis ensures that if the skill is interrupted, crashes, or times out, all findings up to that point are preserved.
Update.sb-pentest-context.json with results:
{
"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.
📁 Evidence Directory: .sb-pentest-evidence/04-storage-audit/
| File | Content |
|---|---|
buckets-config.json | All bucket configurations |
buckets/[name]/file-list.json | File listing per bucket |
{
"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
}
}
# === 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 — Attempt to read filessupabase-audit-buckets-public — Find misconfigured public bucketssupabase-audit-storage-rls — Test storage RLS policiesWeekly Installs
87
Repository
GitHub Stars
32
First Seen
Jan 31, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
claude-code70
codex64
opencode62
gemini-cli59
github-copilot54
cursor54
Supabase Postgres 最佳实践指南 - 8大类别性能优化规则与SQL示例
76,000 周安装