supabase-audit-auth-signup について
Supabase のセキュリティ監査向けスキルで、ユーザー登録フローの問題や設定不備を検査します。登録可否、メール検証、レート制限、一時メール、パスワード要件、応答情報を確認し、結果を逐次記録します。
主な機能
- 01登録が有効かを確認
- 02メール検証と一時メールをテスト
- 03登録のレート制限をテスト
- 04パスワード要件と応答を確認
- 05監査結果の逐次記録
活用シーン
- 01登録を制限すべきかの確認
- 02登録悪用リスクの検査
- 03レート制限と弱いパスワード要件の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yoanbernabeu/ supabase-pentest-skills --skill supabase-audit-auth-signupインストール後、Claude Code で/supabase-audit-auth-signupを入力して読み込まれたか確認します。
詳細
サインアップフロー監査
🔴 重大:コンテキストファイルの段階的な更新が必須です
最後にまとめてではなく、作業を進めながらコンテキストファイルに書き込む必要があります。
- 各テストの完了後、直ちに
.sb-pentest-context.jsonに書き込んでください- 各テストの前と後に
.sb-pentest-audit.logに記録してください- スキルの実行が完了するまで、ファイルの更新を待たないでください
- スキルがクラッシュまたは中断された場合に備え、それまでの調査結果はすべて保存済みである必要があります
これは任意ではありません。段階的に書き込まないことは重大なエラーです。
このスキルでは、ユーザー登録フローにセキュリティ上の問題や設定ミスがないかテストします。
このスキルを使用する場面
- サインアップが適切に制限されているか確認する
- サインアップの悪用につながる攻撃手法をテストする
- 登録時のレート制限を確認する
- 認証セキュリティ監査の一環として実施する
前提条件
- Supabase の URL と anon key が利用可能である
- 認証設定の監査が完了している(推奨)
サインアップのセキュリティが重要な理由
サインアップを公開すると、次のようなリスクが生じる可能性があります。
| リスク | 説明 |
|---|---|
| スパムアカウント | ボットが偽のアカウントを作成する |
| リソースの悪用 | 無料プランを悪用される |
| メールのスパム | サービスを使ってメールが送信される |
| データの汚染 | データベースに偽データが登録される |
| 攻撃対象領域 | アカウントが増えるほど、攻撃経路も増える |
実施するテスト
| テスト | 目的 |
|---|---|
| サインアップの可否 | 登録が公開されているか |
| メールアドレスの検証 | 無効なメールアドレスが受け入れられるか |
| レート制限 | 多数のアカウントを作成できるか |
| 使い捨てメール | 一時的なメールアドレスがブロックされるか |
| パスワードポリシー | どのようなパスワードが受け入れられるか |
| レスポンス情報 | どのような情報が漏えいするか |
使用方法
基本的なサインアップテスト
Test signup security on my Supabase project
特定の項目を確認する
Test if disposable emails are blocked for signup
出力形式
═══════════════════════════════════════════════════════════
SIGNUP FLOW AUDIT
═══════════════════════════════════════════════════════════
Project: abc123def.supabase.co
Endpoint: /auth/v1/signup
─────────────────────────────────────────────────────────
Signup Availability
─────────────────────────────────────────────────────────
Status: ✅ OPEN (Anyone can register)
Test Result:
POST /auth/v1/signup
Body: {"email": "[email protected]", "password": "TestPass123!"}
Response: 200 OK - Account created
Assessment: Signup is publicly available.
Review if this is intended.
─────────────────────────────────────────────────────────
Email Validation
─────────────────────────────────────────────────────────
Valid email formats:
├── [email protected]: ✅ Accepted (expected)
├── [email protected]: ✅ Accepted (expected)
└── [email protected]: ✅ Accepted (expected)
Invalid email formats:
├── user@: ❌ Rejected (good)
├── @domain.com: ❌ Rejected (good)
├── [email protected]: ❌ Rejected (good)
└── not-an-email: ❌ Rejected (good)
Disposable Email Test:
├── [email protected]: ✅ Accepted ← 🟠 P2
├── [email protected]: ✅ Accepted ← 🟠 P2
└── [email protected]: ✅ Accepted ← 🟠 P2
Finding: Disposable emails are not blocked.
Risk: Users can create throwaway accounts.
Recommendation: Consider using an email validation
service or blocklist in your application logic.
─────────────────────────────────────────────────────────
Password Policy
─────────────────────────────────────────────────────────
Minimum Length Test:
├── "12345" (5 chars): ❌ Rejected
├── "123456" (6 chars): ✅ Accepted ← P2 Short
└── "1234567890" (10 chars): ✅ Accepted
Current Policy: Minimum 6 characters
Weak Password Test:
├── "password": ✅ Accepted ← 🟠 P2
├── "123456": ✅ Accepted ← 🟠 P2
├── "qwerty123": ✅ Accepted ← 🟠 P2
└── "letmein": ✅ Accepted ← 🟠 P2
Finding: Common weak passwords are accepted.
Recommendation:
1. Increase minimum length to 8+ characters
2. Consider password strength requirements
3. Check against common password lists
─────────────────────────────────────────────────────────
Rate Limiting
─────────────────────────────────────────────────────────
Signup Rate Test (same IP):
├── Request 1: ✅ 200 OK
├── Request 2: ✅ 200 OK
├── Request 3: ✅ 200 OK
├── Request 4: ❌ 429 Too Many Requests
└── Retry-After: 3600 seconds
Rate Limit: 3 signups/hour per IP
Assessment: ✅ Rate limiting is active (good)
─────────────────────────────────────────────────────────
Information Disclosure
─────────────────────────────────────────────────────────
Existing Email Test:
POST /auth/v1/signup (with existing email)
Response: "User already registered"
Finding: 🟠 P2 - Response reveals email existence
This allows:
├── Email enumeration attacks
├── Knowing if someone has an account
└── Targeted phishing attempts
Recommendation: Use generic message like
"Check your email to continue" for both new
and existing accounts.
─────────────────────────────────────────────────────────
Email Confirmation
─────────────────────────────────────────────────────────
Status: ❌ NOT REQUIRED (confirmed in auth-config)
Test: Created account and checked session
Result: User immediately authenticated without
email confirmation.
─────────────────────────────────────────────────────────
Summary
─────────────────────────────────────────────────────────
Signup: Open to public
Rate Limiting: ✅ Active (3/hour)
Email Confirmation: ❌ Not required
Findings:
├── P1: Email confirmation disabled
├── P2: Disposable emails accepted
├── P2: Weak passwords accepted
└── P2: Email enumeration possible
Security Score: 5/10
Priority Actions:
1. Enable email confirmation
2. Strengthen password policy
3. Consider disposable email blocking
4. Use generic error messages
═══════════════════════════════════════════════════════════
テストの詳細
使い捨てメールの検出
テスト対象となる、一般的な使い捨てメールのドメイン:
- mailinator.com
- tempmail.com
- guerrillamail.com
- 10minutemail.com
- throwaway.email
弱いパスワードのリスト
テスト対象となる、一般的なパスワード:
- password、password123
- 123456、12345678
- qwerty、qwerty123
- letmein、welcome
- admin、administrator
レート制限のテスト
Attempt 1: 200 OK
Attempt 2: 200 OK
Attempt 3: 200 OK
Attempt 4: 429 Too Many Requests
コンテキストの出力
{
"signup_audit": {
"timestamp": "2025-01-31T13:00:00Z",
"signup_open": true,
"rate_limit": {
"enabled": true,
"limit": 3,
"period": "hour"
},
"email_validation": {
"basic_validation": true,
"disposable_blocked": false
},
"password_policy": {
"min_length": 6,
"weak_passwords_blocked": false
},
"information_disclosure": {
"email_enumeration": true
},
"findings": [
{
"severity": "P1",
"issue": "Email confirmation disabled"
},
{
"severity": "P2",
"issue": "Disposable emails accepted"
},
{
"severity": "P2",
"issue": "Weak passwords accepted"
},
{
"severity": "P2",
"issue": "Email enumeration possible"
}
]
}
}
修正例
使い捨てメールをブロックする
// In your signup handler or Edge Function
import { isDisposable } from 'email-validator-package';
if (isDisposable(email)) {
throw new Error('Please use a permanent email address');
}
パスワード要件を強化する
// Custom password validation
function validatePassword(password: string): boolean {
if (password.length < 8) return false;
if (!/[A-Z]/.test(password)) return false;
if (!/[a-z]/.test(password)) return false;
if (!/[0-9]/.test(password)) return false;
return true;
}
メールアドレスの列挙を防ぐ
// Always return same message
async function signup(email, password) {
try {
await supabase.auth.signUp({ email, password });
} catch (error) {
// Don't reveal if email exists
}
return { message: 'Check your email to continue' };
}
サインアップを制限する
サインアップを招待制にする場合:
// Use admin API to invite users
const { data, error } = await supabaseAdmin.auth.admin.inviteUserByEmail(
'[email protected]'
);
// Or disable signup in dashboard and use:
const { data, error } = await supabaseAdmin.auth.admin.createUser({
email: '[email protected]',
email_confirm: true
});
必須:コンテキストファイルの段階的な更新
⚠️ このスキルでは、実行中に追跡ファイルを段階的に更新する必要があります。最後にまとめて更新するだけではいけません。
重要なルール:作業を進めながら書き込む
書き込みを最後にまとめて行ってはいけません。代わりに、次のようにしてください。
- 各サインアップテストの前 →
.sb-pentest-audit.logに操作を記録する - 脆弱性が見つかった後 →
.sb-pentest-context.jsonを直ちに更新する - レート制限テストの後 → 結果を直ちに記録する
これにより、スキルが中断、クラッシュ、またはタイムアウトした場合も、それまでの調査結果がすべて保持されます。
必須の操作(段階的に実施)
-
結果を
.sb-pentest-context.jsonに更新する:{ "signup_audit": { "timestamp": "...", "signup_open": true, "rate_limit": { ... }, "findings": [ ... ] } } -
.sb-pentest-audit.logに記録する:[TIMESTAMP] [supabase-audit-auth-signup] [START] Testing signup security [TIMESTAMP] [supabase-audit-auth-signup] [FINDING] P2: Weak passwords accepted [TIMESTAMP] [supabase-audit-auth-signup] [CONTEXT_UPDATED] .sb-pentest-context.json updated -
ファイルが存在しない場合は、書き込み前に作成する。
コンテキストファイルを更新しないことは認められません。
必須:証拠の収集
📁 証拠ディレクトリ: .sb-pentest-evidence/05-auth-audit/signup-tests/
作成する証拠ファイル
| ファイル | 内容 |
|---|---|
signup-tests/open-signup.json | サインアップの可否テスト |
signup-tests/weak-password.json | 弱いパスワードが受け入れられるかのテスト |
signup-tests/disposable-email.json | 使い捨てメールのテスト |
signup-tests/rate-limit.json | レート制限のテスト |
証拠の形式
{
"evidence_id": "AUTH-SIGNUP-001",
"timestamp": "2025-01-31T10:55:00Z",
"category": "auth-audit",
"type": "signup_test",
"tests": [
{
"test_name": "weak_password_acceptance",
"severity": "P2",
"request": {
"method": "POST",
"url": "https://abc123def.supabase.co/auth/v1/signup",
"body": {"email": "[email protected]", "password": "123456"},
"curl_command": "curl -X POST '$URL/auth/v1/signup' -H 'apikey: $ANON_KEY' -H 'Content-Type: application/json' -d '{\"email\": \"[email protected]\", \"password\": \"123456\"}'"
},
"response": {
"status": 200,
"message": "User created"
},
"result": "VULNERABLE",
"impact": "Weak passwords (6 chars) accepted"
},
{
"test_name": "disposable_email",
"severity": "P2",
"request": {
"body": {"email": "[email protected]", "password": "Test123456!"}
},
"response": {
"status": 200,
"message": "User created"
},
"result": "VULNERABLE",
"impact": "Disposable emails not blocked"
}
]
}
関連スキル
supabase-audit-auth-config— 認証設定全般supabase-audit-auth-users— ユーザー列挙テストsupabase-audit-rls— RLS によるユーザーデータの保護