关于 supabase-audit-buckets-public
用于检查 Supabase 存储公共存储桶配置和敏感文件暴露情况的安全审计技能,适合部署前或针对存储进行专项检查。它按内容类型和风险级别分类存储桶,并逐步记录发现。
主要功能
- 01识别配置错误的公共存储桶
- 02按文件内容分类暴露风险
- 03提供私有化和访问限制建议
- 04逐桶更新上下文并记录审计日志
- 05收集公共 URL 测试证据
适用场景
- 01部署前检查存储桶是否意外公开
- 02排查公共存储桶中的备份或秘密文件
- 03配置变更后复核存储安全
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ yoanbernabeu/ supabase-pentest-skills --skill supabase-audit-buckets-public安装后在 Claude Code 中输入/supabase-audit-buckets-public确认已加载。
详细介绍
公共存储桶审计
🔴 严重:必须渐进式更新文件
必须在执行过程中写入上下文文件,而不是只在最后写入。
- 每分析完一个存储桶后,立即写入
.sb-pentest-context.json- 每项测试前后都要写入
.sb-pentest-audit.log- 不要等到技能执行完毕才更新文件
- 如果技能崩溃或中断,之前的所有发现都必须已经保存
这不是可选项。未能渐进式写入属于严重错误。
此技能专门用于识别配置错误的公共存储桶以及暴露的敏感内容。
何时使用此技能
- 快速检查公共存储桶是否存在配置错误
- 怀疑公共存储中存在敏感数据时
- 专门检查存储安全时
- 部署到生产环境之前
前提条件
- 可获取 Supabase URL 和 anon key
公共存储桶为何存在风险
公共存储桶允许:
| 访问类型 | 说明 |
|---|---|
| 直接 URL | 任何拥有 URL 的人都可以下载 |
| 枚举 | 可能可以列出文件 |
| 无身份验证 | 无需身份验证 |
| 缓存 | CDN 可能会缓存敏感文件 |
常见配置错误场景
- 开发失误 — 开发期间将存储桶设为公开
- 存储桶选错 — 敏感文件被上传到公共存储桶
- 遗留问题 — RLS 出现之前,存储桶就已设为公开
- 本意如此但做法错误 — 误以为“没人知道 URL”
用法
快速检查公共存储桶
Check for misconfigured public buckets
深度扫描
Deep scan public buckets for sensitive content
输出格式
═══════════════════════════════════════════════════════════
PUBLIC BUCKET SECURITY AUDIT
═══════════════════════════════════════════════════════════
Project: abc123def.supabase.co
─────────────────────────────────────────────────────────
Public Bucket Discovery
─────────────────────────────────────────────────────────
Public Buckets Found: 3/5
─────────────────────────────────────────────────────────
1. avatars ✅ APPROPRIATE
─────────────────────────────────────────────────────────
Status: Public (Expected)
Purpose: User profile pictures
Content Analysis:
├── All files are images (jpg, png, webp)
├── No sensitive filenames detected
├── File sizes appropriate for avatars (< 1MB)
└── No metadata concerns
Assessment: This bucket appropriately contains only
public user-facing content.
─────────────────────────────────────────────────────────
2. uploads 🟠 P1 - NEEDS REVIEW
─────────────────────────────────────────────────────────
Status: Public (Unexpected for this content)
Purpose: User file uploads
Content Analysis:
├── Mixed file types (PDF, DOC, images)
├── Some sensitive filenames detected
└── Should likely be private with RLS
Sensitive Content Indicators:
├── 12 files with 'invoice' in name
├── 8 files with 'contract' in name
├── 3 files with 'passport' in name
└── 156 PDF files (may contain sensitive data)
Risk Assessment:
└── 🟠 User-uploaded content publicly accessible
Anyone with filename can access any user's files
Recommendation:
```sql
-- Make bucket private
UPDATE storage.buckets
SET public = false
WHERE name = 'uploads';
-- Add user-specific RLS
CREATE POLICY "Users access own uploads"
ON storage.objects FOR ALL
USING (
bucket_id = 'uploads'
AND auth.uid()::text = (storage.foldername(name))[1]
);
───────────────────────────────────────────────────────── 3. backups 🔴 P0 - 严重配置错误 ─────────────────────────────────────────────────────────
状态:公开(绝不应设为公开) 用途:数据库备份
⚠️ 严重:备份文件可被公开访问!
暴露的内容: ├── 🔴 db-backup-2025-01-30.sql(125MB) │ └── 包含所有用户数据的完整数据库转储 ├── 🔴 db-backup-2025-01-29.sql(124MB) │ └── 前一天的备份 ├── 🔴 users-export.csv(2.3MB) │ └── 包含电子邮件、姓名的用户数据导出文件 ├── 🔴 secrets.env(1KB) │ └── 包含 API 密钥和密码! └── 🔴 .env.production(1KB) └── 生产环境机密信息!
公共 URL(当前可访问): https://abc123def.supabase.co/storage/v1/object/public/backups/db-backup-2025-01-30.sql https://abc123def.supabase.co/storage/v1/object/public/backups/secrets.env
影响: ├── 可下载完整数据库 ├── 所有用户 PII 均已暴露 ├── 所有 API 机密信息均已暴露 └── 整个应用都可能遭到入侵
═══════════════════════════════════════════════════════════ 🚨 需要立即采取行动 🚨 ═══════════════════════════════════════════════════════════
-
立即将存储桶设为私有:
UPDATE storage.buckets SET public = false WHERE name = 'backups'; -
删除公共文件: 删除所有敏感文件,或将其移出公共访问范围
-
轮换所有已暴露的机密信息:
- Stripe API 密钥
- 数据库密码
- JWT 机密信息
- 已暴露文件中的任何其他密钥
-
审计访问日志: 检查文件是否曾被未授权方访问
-
事件响应: 将此事视为数据泄露,并遵循你的 事件响应流程
───────────────────────────────────────────────────────── 摘要 ─────────────────────────────────────────────────────────
公共存储桶:3 ├── ✅ 合理:1(avatars) ├── 🟠 P1 需审查:1(uploads) └── 🔴 P0 严重:1(backups)
暴露的敏感文件:47 暴露的机密文件:2
严重发现:数据库备份和机密信息 可通过直接 URL 公开访问
═══════════════════════════════════════════════════════════
## Bucket Classification
The skill classifies buckets by content:
| Classification | Criteria | Action |
|----------------|----------|--------|
| **Appropriate Public** | Profile images, public assets | None needed |
| **Needs Review** | User uploads, mixed content | Consider making private |
| **Critical Misconfiguration** | Backups, secrets, exports | Immediate remediation |
## Sensitive Content Patterns
### P0 - Critical (Never Public)
- `*.sql` - Database dumps
- `*.env*` - Environment files
- `*secret*`, `*credential*` - Secrets
- `*backup*` - Backup files
- `*export*` - Data exports
### P1 - High (Usually Private)
- `*invoice*`, `*payment*` - Financial
- `*contract*`, `*agreement*` - Legal
- `*passport*`, `*id*`, `*license*` - Identity
- User-uploaded documents
### P2 - Medium (Review Needed)
- Configuration files
- Log files
- Debug exports
## Context Output
```json
{
"public_bucket_audit": {
"timestamp": "2025-01-31T12:00:00Z",
"public_buckets": 3,
"findings": [
{
"bucket": "backups",
"severity": "P0",
"issue": "Database backups and secrets publicly accessible",
"exposed_files": 45,
"critical_files": [
"db-backup-2025-01-30.sql",
"secrets.env",
".env.production"
],
"remediation": "Make bucket private immediately, rotate secrets"
}
]
}
}
预防检查清单
修复问题后,请实施以下控制措施:
1. 默认使用私有存储桶
-- Supabase creates buckets public by default in UI
-- Always verify and change to private if needed
UPDATE storage.buckets
SET public = false
WHERE name = 'new-bucket';
2. 限制存储桶创建
-- Only allow admin to create buckets
REVOKE INSERT ON storage.buckets FROM authenticated;
REVOKE INSERT ON storage.buckets FROM anon;
3. 文件上传验证
// Validate file type before upload
const allowedTypes = ['image/jpeg', 'image/png'];
if (!allowedTypes.includes(file.type)) {
throw new Error('Invalid file type');
}
// Use user-specific paths
const path = `${user.id}/${file.name}`;
await supabase.storage.from('uploads').upload(path, file);
4. 定期审计
定期运行此技能:
- 每次生产部署前
- 每周自动扫描
- 任何存储配置变更后
强制要求:渐进式更新上下文文件
⚠️ 此技能必须在执行过程中逐步更新跟踪文件,不能只在最后更新。
关键规则:边做边写
不要将所有写入操作拖到最后。应按以下方式操作:
- 分析每个存储桶之前 → 将操作记录到
.sb-pentest-audit.log - 发现每项错误配置后 → 立即更新
.sb-pentest-context.json - 检测到每个敏感文件后 → 立即记录发现结果
这样可以确保即使技能中断、崩溃或超时,截至当时的所有发现都能得到保留。
必须执行的操作(渐进式)
-
更新
.sb-pentest-context.json,写入结果:{ "public_bucket_audit": { "timestamp": "...", "public_buckets": 3, "findings": [ ... ] } } -
记录到
.sb-pentest-audit.log:[TIMESTAMP] [supabase-audit-buckets-public] [START] Auditing public buckets [TIMESTAMP] [supabase-audit-buckets-public] [FINDING] P0: backups bucket is public [TIMESTAMP] [supabase-audit-buckets-public] [CONTEXT_UPDATED] .sb-pentest-context.json updated -
如果文件不存在,请在写入前创建文件。
不更新上下文文件是不可接受的。
强制要求:收集证据
📁 证据目录: .sb-pentest-evidence/04-storage-audit/public-url-tests/
需要创建的证据文件
| 文件 | 内容 |
|---|---|
public-url-tests/[bucket]-access.json | 公共 URL 访问测试结果 |
public-url-tests/sensitive-content.json | 发现的敏感内容 |
证据格式
{
"evidence_id": "STG-PUB-001",
"timestamp": "2025-01-31T10:45:00Z",
"category": "storage-audit",
"type": "public_bucket_audit",
"severity": "P0",
"bucket": "backups",
"public_url_test": {
"url": "https://abc123def.supabase.co/storage/v1/object/public/backups/secrets.env",
"curl_command": "curl -I 'https://abc123def.supabase.co/storage/v1/object/public/backups/secrets.env'",
"response_status": 200,
"content_type": "text/plain",
"accessible": true
},
"assessment": {
"classification": "critical_misconfiguration",
"should_be_public": false,
"contains_sensitive_data": true,
"file_types_exposed": ["sql", "env", "csv"]
},
"remediation": {
"immediate": "UPDATE storage.buckets SET public = false WHERE name = 'backups';",
"secrets_to_rotate": ["All keys in secrets.env"],
"incident_response": "Consider this a data breach"
}
}
相关技能
supabase-audit-buckets-list— 列出所有存储桶supabase-audit-buckets-read— 测试文件访问supabase-report— 生成综合报告