mcpField
S
supabase-audit-buckets-read

supabase-audit-buckets-read

github.com/yoanbernabeuセキュリティ71481 回インストール39 週間前に更新
リポジトリ

supabase-audit-buckets-read について

Supabase のセキュリティ監査向けスキルで、Storage バケット内のファイルアクセスを試して権限を検証します。一覧、メタデータ、サンプルのダウンロード、公開 URL を確認し、結果と証拠を逐次記録します。

主な機能

  1. 01ファイル一覧とメタデータのアクセス検査
  2. 02サンプルを取得してコンテンツタイプを確認
  3. 03公開 URL へのアクセス確認
  4. 04機密ファイルと内容の検出
  5. 05結果と証拠の逐次記録

活用シーン

  1. 01バケットの RLS 権限の検証
  2. 02公開された機密ファイルの発見
  3. 03アクセス可能なファイルと監査証拠の記録

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/yoanbernabeu/supabase-pentest-skills --skill supabase-audit-buckets-read

インストール後、Claude Code で/supabase-audit-buckets-readを入力して読み込まれたか確認します。

詳細

バケットファイルアクセスのテスト

🔴 重大:ファイルの進行に応じた更新が必須です

コンテキストファイルには、最後にまとめてではなく、作業を進めながら必ず書き込んでください。

  • 各バケットのテスト直後に .sb-pentest-context.json にただちに書き込む
  • 各ファイルアクセスのテストの前後に .sb-pentest-audit.log に記録する
  • スキルの完了までファイルの更新を待たないこと
  • スキルがクラッシュまたは中断された場合でも、それまでの調査結果はすべて保存済みである必要があります

これは任意ではありません。進行に応じた書き込みを怠ることは重大なエラーです。

このスキルでは、ストレージバケット内のファイルへの実際のアクセスをテストし、権限を検証します。

このスキルを使用するタイミング

  • バケットの一覧表示後に、実際にアクセスできるかを検証するとき
  • ストレージの RLS ポリシーの有効性をテストするとき
  • 機密ファイルが露出していないか確認するとき
  • アクセス可能なファイルを記録するとき

前提条件

  • バケットの一覧が取得済み(必要に応じて自動で実行)
  • Anon キーが利用可能

動作の仕組み

このスキルでは、次のことを試みます。

  1. 各バケット内のファイルを一覧表示する
  2. ファイルのメタデータを読み取る
  3. サンプルファイルをダウンロードする(コンテンツタイプの検証用)
  4. パブリック URL へのアクセスを確認する

重要: これは読み取り専用です。ファイルの変更や削除は行いません。

テスト方法

バケットの種類実施するテスト
パブリック直接 URL アクセス、一覧表示、メタデータ
プライベートAnon キーによる API 一覧表示、認証済みアクセス

使用方法

基本的な読み取りテスト
Test read access on storage buckets
特定のバケット
Test file access on the documents bucket
一覧表示のみ(ダウンロードなし)
List accessible files without downloading content

出力形式

═══════════════════════════════════════════════════════════
 BUCKET FILE ACCESS TEST
═══════════════════════════════════════════════════════════

 Project: abc123def.supabase.co
 Buckets Tested: 5

 ─────────────────────────────────────────────────────────
 avatars (Public Bucket)
 ─────────────────────────────────────────────────────────

 Status: ✅ Expected Access
 Files Found: 1,247

 Sample Files:
 ├── user-550e8400.jpg (45KB) - Public URL works
 ├── user-6ba7b810.png (32KB) - Public URL works
 └── default.png (12KB) - Public URL works

 Access Methods:
 ├── Public URL: ✅ Accessible
 ├── API Listing: ✅ Works
 └── Metadata: ✅ Visible

 Assessment: Expected behavior for avatar storage.

 ─────────────────────────────────────────────────────────
 documents (Private Bucket)
 ─────────────────────────────────────────────────────────

 Status: ✅ PROPERLY PROTECTED
 Files Found: 0 (via anon key)

 Access Methods:
 ├── Public URL: ❌ 403 Forbidden (correct)
 ├── API Listing: ❌ Empty result (RLS working)
 └── Metadata: ❌ Not accessible (correct)

 Assessment: RLS policies working correctly.

 ─────────────────────────────────────────────────────────
 uploads (Public Bucket)
 ─────────────────────────────────────────────────────────

 Status: 🟠 P1 - SENSITIVE FILES EXPOSED
 Files Found: 3,891

 Sensitive Files Detected:
 ├── 🔴 invoice-2025-001.pdf - Contains financial data
 ├── 🔴 contract-signed.pdf - Legal document
 ├── 🔴 id-verification.jpg - Personal ID photo!
 ├── ⚠️ database-export.csv - Possible data export
 └── ⚠️ config.json - Configuration file

 File Types Distribution:
 ├── PDF: 1,234 (31%)
 ├── Images: 2,100 (54%)
 ├── Documents: 450 (12%)
 └── Other: 107 (3%)

 Assessment: Bucket contains sensitive files that should not be public!

 ─────────────────────────────────────────────────────────
 backups (Public - CRITICAL)
 ─────────────────────────────────────────────────────────

 Status: 🔴 P0 - CRITICAL DATA EXPOSURE
 Files Found: 45

 Exposed Files:
 ├── 🔴 db-backup-2025-01-30.sql (125MB) - DATABASE BACKUP!
 ├── 🔴 db-backup-2025-01-29.sql (124MB) - DATABASE BACKUP!
 ├── 🔴 users-export.csv (2.3MB) - USER DATA EXPORT!
 ├── 🔴 secrets.env (1KB) - ENVIRONMENT SECRETS!
 └── 🔴 .env.production (1KB) - PRODUCTION SECRETS!

 Sample Content (secrets.env):
 ┌─────────────────────────────────────────────────────────┐
 │ STRIPE_SECRET_KEY=sk_live_xxxxxxxxxxxx                 │
 │ DATABASE_URL=postgresql://postgres:xxx@...             │
 │ JWT_SECRET=super-secret-jwt-key                        │
 └─────────────────────────────────────────────────────────┘

 ⚠️ IMMEDIATE ACTION REQUIRED:
 1. Make bucket private NOW
 2. Rotate ALL exposed secrets
 3. Delete backup files from public access
 4. Audit for unauthorized access in logs

 ─────────────────────────────────────────────────────────
 temp (Private Bucket)
 ─────────────────────────────────────────────────────────

 Status: ✅ PROPERLY PROTECTED
 Files Found: 0 (via anon key)
 Assessment: Access correctly restricted.

 ─────────────────────────────────────────────────────────
 Summary
 ─────────────────────────────────────────────────────────

 P0 Critical: 1 bucket (backups - DB dumps & secrets exposed)
 P1 High: 1 bucket (uploads - sensitive documents in public bucket)
 Protected: 2 buckets (documents, temp)
 Expected: 1 bucket (avatars)

 Total Files Accessible: 5,183
 Sensitive Files Exposed: 52
 Secret Files Exposed: 3

 Immediate Actions:
 1. 🔴 DELETE or make private 'backups' bucket
 2. 🔴 Rotate Stripe key, DB password, JWT secret
 3. 🟠 Move sensitive files from 'uploads' to private bucket
 4. Review all 52 sensitive files for exposure impact

═══════════════════════════════════════════════════════════

機密ファイルの検出

このスキルは、次の方法で機密ファイルを特定します。

ファイル名のパターン
パターンリスク種類
*.sql, backup*P0データベースダンプ
.env*, *secrets*P0シークレットファイル
*password*, *credential*P0認証情報
*invoice*, *payment*P1財務情報
*contract*, *agreement*P1法的文書
*id*, *passport*, *license*P1身元情報
*export*, *dump*P1データのエクスポート
コンテンツの検出

アクセス可能なファイルについて、このスキルはコンテンツのサンプルから次の情報を検出します。

  • API キー(sk_live_、pk_test_ などのパターン)
  • データベースの認証情報
  • JWT シークレット
  • 個人情報のパターン

コンテキスト出力

{
  "storage_access": {
    "timestamp": "2025-01-31T11:30:00Z",
    "buckets_tested": 5,
    "findings": [
      {
        "bucket": "backups",
        "severity": "P0",
        "public": true,
        "files_exposed": 45,
        "sensitive_files": [
          {
            "path": "db-backup-2025-01-30.sql",
            "size": 131072000,
            "type": "database_backup",
            "risk": "Full database accessible"
          },
          {
            "path": "secrets.env",
            "size": 1024,
            "type": "secrets",
            "exposed_secrets": ["STRIPE_SECRET_KEY", "DATABASE_URL", "JWT_SECRET"]
          }
        ]
      }
    ],
    "summary": {
      "total_files_accessible": 5183,
      "sensitive_files": 52,
      "secret_files": 3
    }
  }
}

修正手順

露出したシークレットへの対応
# 1. Rotate Stripe keys
# Stripe Dashboard → Developers → API Keys → Roll Keys

# 2. Change database password
# Supabase Dashboard → Settings → Database → Reset Password

# 3. Regenerate JWT secret
# Supabase Dashboard → Settings → API → Regenerate JWT Secret

# 4. Update application environment variables
# Redeploy with new secrets
パブリックバケットの修正
-- Make bucket private
UPDATE storage.buckets
SET public = false
WHERE name = 'backups';

-- Delete sensitive files or move to secure location
DELETE FROM storage.objects
WHERE bucket_id = 'backups';
アップロード用バケット
-- Add RLS to restrict access
CREATE POLICY "Users access own uploads"
  ON storage.objects FOR ALL
  USING (
    bucket_id = 'uploads'
    AND auth.uid()::text = (storage.foldername(name))[1]
  );

よくある問題

❌ 問題: プライベートバケット内のファイルを一覧表示できない
✅ 解決策: これは正しい動作です。RLS が機能しています。

❌ 問題: スキャンするファイルの数が多い
✅ 解決策: 大きなバケットにはサンプリングモードを使用してください。

❌ 問題: ファイルのダウンロードに失敗する
✅ 解決策: RLS による制限、またはネットワークの問題の可能性があります。

必須:コンテキストファイルの進行に応じた更新

⚠️ このスキルは、実行中に追跡ファイルを進行に応じて更新しなければなりません。最後にまとめて更新するだけでは不十分です。

重要なルール:作業を進めながら書き込む

書き込みを最後にまとめて行うのは避けてください。代わりに、次のようにします。

  1. 各バケットのテスト前 → .sb-pentest-audit.log に操作を記録する
  2. 機密ファイルを見つけるたびに → .sb-pentest-context.json をただちに更新する
  3. 各バケットの完了後 → 概要を記録する

これにより、スキルが中断、クラッシュ、またはタイムアウトした場合でも、その時点までの調査結果をすべて保持できます。

必須の操作(進行に応じて実施)
  1. 結果を .sb-pentest-context.json に更新する:

    {
      "storage_access": {
        "timestamp": "...",
        "buckets_tested": 5,
        "findings": [ ... ],
        "summary": { "total_files_accessible": 5183, ... }
      }
    }
    
  2. .sb-pentest-audit.log に記録する:

    [TIMESTAMP] [supabase-audit-buckets-read] [START] Testing bucket file access
    [TIMESTAMP] [supabase-audit-buckets-read] [FINDING] P0: backups bucket has exposed secrets
    [TIMESTAMP] [supabase-audit-buckets-read] [CONTEXT_UPDATED] .sb-pentest-context.json updated
    
  3. ファイルが存在しない場合は、書き込む前に作成する。

コンテキストファイルを更新しないことは許容されません。

必須:証拠の収集

📁 証拠ディレクトリ: .sb-pentest-evidence/04-storage-audit/buckets/

作成する証拠ファイル
ファイル内容
buckets/[name]/file-list.jsonバケット内で見つかったファイル
buckets/[name]/sensitive-files.json検出された機密ファイル
buckets/[name]/sample-contents/編集済みコンテンツのサンプル
機密ファイル露出時の証拠形式
{
  "evidence_id": "STG-READ-001",
  "timestamp": "2025-01-31T10:40:00Z",
  "category": "storage-audit",
  "type": "file_access",
  "severity": "P0",

  "bucket": "backups",
  "public": true,

  "files_found": 45,
  "sensitive_files": [
    {
      "path": "db-backup-2025-01-30.sql",
      "size": 131072000,
      "type": "database_backup",
      "public_url": "https://abc123def.supabase.co/storage/v1/object/public/backups/db-backup-2025-01-30.sql",
      "curl_command": "curl -o backup.sql 'https://abc123def.supabase.co/storage/v1/object/public/backups/db-backup-2025-01-30.sql'"
    },
    {
      "path": "secrets.env",
      "size": 1024,
      "type": "secrets_file",
      "content_sample": "STRIPE_SECRET_KEY=sk_live_[REDACTED]\nDATABASE_URL=postgresql://[REDACTED]",
      "exposed_secrets": ["STRIPE_SECRET_KEY", "DATABASE_URL", "JWT_SECRET"]
    }
  ],

  "impact": {
    "data_breach": true,
    "secrets_exposed": true,
    "affected_records": "All database records",
    "credentials_to_rotate": ["Stripe API key", "Database password", "JWT secret"]
  }
}
curl-commands.sh に追加する
# === STORAGE FILE ACCESS TESTS ===
# List files in backups bucket
curl -s "$SUPABASE_URL/storage/v1/object/list/backups" \
  -H "apikey: $ANON_KEY"

# Direct access to public file (P0 if accessible)
curl -I "https://abc123def.supabase.co/storage/v1/object/public/backups/secrets.env"

# Download exposed backup (for evidence - be careful with size)
# curl -o evidence-backup-sample.sql "https://abc123def.supabase.co/storage/v1/object/public/backups/db-backup-2025-01-30.sql" | head -1000

関連スキル

  • supabase-audit-buckets-list — まずバケットを一覧表示します
  • supabase-audit-buckets-public — 公開アクセスの問題に重点を置きます
  • supabase-report — 完全なレポートを生成します

コメント