supabase-audit-buckets-list について
Supabase のセキュリティ監査向けスキルで、プロジェクトの Storage バケットを列挙し、設定を確認します。アクセス検査前の棚卸しに使え、結果をコンテキストや監査ログへ逐次記録します。
主な機能
- 01Storage バケットの列挙
- 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 ポリシーをテストする