supabase-audit-auth-signup
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSignup Flow Audit
注册流程审计
🔴 CRITICAL: PROGRESSIVE FILE UPDATES REQUIREDYou MUST write to context files AS YOU GO, not just at the end.
- Write to
IMMEDIATELY after each test completed.sb-pentest-context.json- Log to
BEFORE and AFTER each test.sb-pentest-audit.log- 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 tests the user registration flow for security issues and misconfigurations.
🔴 CRITICAL: PROGRESSIVE FILE UPDATES REQUIRED你必须逐步写入上下文文件,而不是仅在最后统一写入。
- 每次测试完成后立即写入
.sb-pentest-context.json- 每次测试前后都要记录到
.sb-pentest-audit.log- 不要等到技能执行完毕再更新文件
- 如果技能崩溃或被中断,所有已发现的结果必须已保存
此要求为强制性,未逐步写入属于严重错误。
本技能用于测试用户注册流程中的安全问题和配置错误。
When to Use This Skill
何时使用此技能
- To verify if signup is appropriately restricted
- To test for signup abuse vectors
- To check rate limiting on registration
- As part of authentication security audit
- 验证注册是否被适当限制
- 测试注册流程中的滥用风险点
- 检查注册环节的速率限制
- 作为身份验证安全审计的一部分
Prerequisites
前置条件
- Supabase URL and anon key available
- Auth config audit completed (recommended)
- 已获取Supabase URL和anon key
- 已完成Auth配置审计(推荐)
Why Signup Security Matters
注册安全的重要性
Open signup can lead to:
| Risk | Description |
|---|---|
| Spam accounts | Bots creating fake accounts |
| Resource abuse | Free tier exploitation |
| Email spam | Using your service to send emails |
| Data pollution | Fake data in your database |
| Attack surface | More accounts = more attack vectors |
开放注册可能导致以下风险:
| 风险 | 描述 |
|---|---|
| 垃圾账号 | 机器人创建虚假账号 |
| 资源滥用 | 免费套餐被恶意利用 |
| 邮件垃圾 | 利用你的服务发送垃圾邮件 |
| 数据污染 | 数据库中混入虚假数据 |
| 攻击面扩大 | 账号越多,潜在攻击点越多 |
Tests Performed
执行的测试
| Test | Purpose |
|---|---|
| Signup availability | Is registration open? |
| Email validation | Does it accept invalid emails? |
| Rate limiting | Can we create many accounts? |
| Disposable emails | Are temp emails blocked? |
| Password policy | What passwords are accepted? |
| Response information | What info is leaked? |
| 测试项 | 目的 |
|---|---|
| 注册可用性 | 注册是否开放? |
| 邮箱验证 | 是否接受无效邮箱? |
| 速率限制 | 是否可以批量创建账号? |
| 临时邮箱检测 | 是否拦截临时邮箱? |
| 密码策略 | 允许使用哪些密码? |
| 响应信息泄露 | 泄露了哪些敏感信息? |
Usage
使用方法
Basic Signup Test
基础注册测试
Test signup security on my Supabase projectTest signup security on my Supabase projectCheck Specific Aspects
检查特定维度
Test if disposable emails are blocked for signupTest if disposable emails are blocked for signupOutput Format
输出格式
═══════════════════════════════════════════════════════════
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": "test-xxxxx@example.com", "password": "TestPass123!"}
Response: 200 OK - Account created
Assessment: Signup is publicly available.
Review if this is intended.
─────────────────────────────────────────────────────────
Email Validation
─────────────────────────────────────────────────────────
Valid email formats:
├── user@domain.com: ✅ Accepted (expected)
├── user+tag@domain.com: ✅ Accepted (expected)
└── user@subdomain.domain.com: ✅ Accepted (expected)
Invalid email formats:
├── user@: ❌ Rejected (good)
├── @domain.com: ❌ Rejected (good)
├── user@.com: ❌ Rejected (good)
└── not-an-email: ❌ Rejected (good)
Disposable Email Test:
├── user@mailinator.com: ✅ Accepted ← 🟠 P2
├── user@tempmail.com: ✅ Accepted ← 🟠 P2
└── user@guerrillamail.com: ✅ 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
══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
SIGNUP FLOW AUDIT
═══════════════════════════════════════════════════════════
Project: abc123def.supabase.co
Endpoint: /auth/v1/signup
─────────────────────────────────────────────────────────
注册可用性
─────────────────────────────────────────────────────────
状态: ✅ 开放(任何人可注册)
测试结果:
POST /auth/v1/signup
请求体: {"email": "test-xxxxx@example.com", "password": "TestPass123!"}
响应: 200 OK - 账号创建成功
评估: 注册对公众开放。请确认是否为预期配置。
─────────────────────────────────────────────────────────
邮箱验证
─────────────────────────────────────────────────────────
有效邮箱格式:
├── user@domain.com: ✅ 被接受(符合预期)
├── user+tag@domain.com: ✅ 被接受(符合预期)
└── user@subdomain.domain.com: ✅ 被接受(符合预期)
无效邮箱格式:
├── user@: ❌ 被拒绝(安全)
├── @domain.com: ❌ 被拒绝(安全)
├── user@.com: ❌ 被拒绝(安全)
└── not-an-email: ❌ 被拒绝(安全)
临时邮箱测试:
├── user@mailinator.com: ✅ 被接受 ← 🟠 P2
├── user@tempmail.com: ✅ 被接受 ← 🟠 P2
└── user@guerrillamail.com: ✅ 被接受 ← 🟠 P2
发现问题: 未拦截临时邮箱。
风险: 用户可创建一次性账号。
建议: 考虑使用邮箱验证服务或在应用逻辑中添加拦截名单。
─────────────────────────────────────────────────────────
密码策略
─────────────────────────────────────────────────────────
最小长度测试:
├── "12345"(5位): ❌ 被拒绝
├── "123456"(6位): ✅ 被接受 ← P2 过短
└── "1234567890"(10位): ✅ 被接受
当前策略: 最小6位字符
弱密码测试:
├── "password": ✅ 被接受 ← 🟠 P2
├── "123456": ✅ 被接受 ← 🟠 P2
├── "qwerty123": ✅ 被接受 ← 🟠 P2
└── "letmein": ✅ 被接受 ← 🟠 P2
发现问题: 允许使用常见弱密码。
建议:
1. 将最小长度提升至8位以上
2. 考虑添加密码强度要求
3. 校验密码是否在常见弱密码列表中
─────────────────────────────────────────────────────────
速率限制
─────────────────────────────────────────────────────────
同IP注册速率测试:
├── 请求1: ✅ 200 OK
├── 请求2: ✅ 200 OK
├── 请求3: ✅ 200 OK
├── 请求4: ❌ 429 Too Many Requests
└── Retry-After: 3600秒
速率限制: 每IP每小时3次注册
评估: ✅ 速率限制已启用(安全)
─────────────────────────────────────────────────────────
信息泄露
─────────────────────────────────────────────────────────
已存在邮箱测试:
POST /auth/v1/signup(使用已注册邮箱)
响应: "User already registered"
发现问题: 🟠 P2 - 响应泄露邮箱已注册
风险:
├── 邮箱枚举攻击
├── 可判断特定用户是否拥有账号
└── 针对性钓鱼攻击
建议: 对新账号和已存在账号均返回通用提示,例如
"请检查邮箱以继续操作"
─────────────────────────────────────────────────────────
邮箱确认
─────────────────────────────────────────────────────────
状态: ❌ 未要求(在auth-config中已确认)
测试: 创建账号并检查会话
结果: 用户无需邮箱确认即可立即登录。
─────────────────────────────────────────────────────────
总结
─────────────────────────────────────────────────────────
注册状态: 对公众开放
速率限制: ✅ 已启用(3次/小时)
邮箱确认: ❌ 未要求
发现问题:
├── P1: 邮箱确认已禁用
├── P2: 允许使用临时邮箱
├── P2: 允许使用弱密码
└── P2: 存在邮箱枚举风险
安全评分: 5/10
优先修复项:
1. 启用邮箱确认
2. 强化密码策略
3. 考虑拦截临时邮箱
4. 使用通用错误提示
═══════════════════════════════════════════════════════════Test Details
测试细节
Disposable Email Detection
临时邮箱检测
Common disposable email domains tested:
- mailinator.com
- tempmail.com
- guerrillamail.com
- 10minutemail.com
- throwaway.email
测试的常见临时邮箱域名:
- mailinator.com
- tempmail.com
- guerrillamail.com
- 10minutemail.com
- throwaway.email
Weak Password List
弱密码列表
Common passwords tested:
- password, password123
- 123456, 12345678
- qwerty, qwerty123
- letmein, welcome
- admin, administrator
测试的常见弱密码:
- password, password123
- 123456, 12345678
- qwerty, qwerty123
- letmein, welcome
- admin, administrator
Rate Limit Testing
速率限制测试
Attempt 1: 200 OK
Attempt 2: 200 OK
Attempt 3: 200 OK
Attempt 4: 429 Too Many RequestsAttempt 1: 200 OK
Attempt 2: 200 OK
Attempt 3: 200 OK
Attempt 4: 429 Too Many RequestsContext Output
上下文输出
json
{
"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"
}
]
}
}json
{
"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"
}
]
}
}Remediation Examples
修复示例
Block Disposable Emails
拦截临时邮箱
typescript
// 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');
}typescript
// 在注册处理函数或Edge Function中
import { isDisposable } from 'email-validator-package';
if (isDisposable(email)) {
throw new Error('Please use a permanent email address');
}Strengthen Password Requirements
强化密码要求
typescript
// 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;
}typescript
// 自定义密码验证
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;
}Prevent Email Enumeration
防止邮箱枚举
typescript
// 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' };
}typescript
// 始终返回相同提示
async function signup(email, password) {
try {
await supabase.auth.signUp({ email, password });
} catch (error) {
// 不泄露邮箱是否已存在
}
return { message: 'Check your email to continue' };
}Restrict Signup
限制注册
If signup should be invite-only:
typescript
// Use admin API to invite users
const { data, error } = await supabaseAdmin.auth.admin.inviteUserByEmail(
'user@example.com'
);
// Or disable signup in dashboard and use:
const { data, error } = await supabaseAdmin.auth.admin.createUser({
email: 'user@example.com',
email_confirm: true
});如果注册应为邀请制:
typescript
// 使用管理员API邀请用户
const { data, error } = await supabaseAdmin.auth.admin.inviteUserByEmail(
'user@example.com'
);
// 或在控制台禁用注册后使用:
const { data, error } = await supabaseAdmin.auth.admin.createUser({
email: 'user@example.com',
email_confirm: true
});MANDATORY: Progressive Context File Updates
MANDATORY: Progressive Context File Updates
⚠️ This skill MUST update tracking files PROGRESSIVELY during execution, NOT just at the end.
⚠️ 此技能必须在执行过程中逐步更新跟踪文件,而非仅在最后统一更新。
Critical Rule: Write As You Go
核心规则: 边执行边写入
DO NOT batch all writes at the end. Instead:
- Before each signup test → Log the action to
.sb-pentest-audit.log - After each vulnerability found → Immediately update
.sb-pentest-context.json - After rate limit tests → Log the results immediately
This ensures that if the skill is interrupted, crashes, or times out, all findings up to that point are preserved.
不要批量写入所有内容。请遵循:
- 每次注册测试前 → 将操作记录到
.sb-pentest-audit.log - 每次发现漏洞后 → 立即更新
.sb-pentest-context.json - 速率限制测试完成后 → 立即记录结果
这样可确保如果技能被中断、崩溃或超时,截至当前的所有发现都已被保存。
Required Actions (Progressive)
要求的逐步操作
-
Updatewith results:
.sb-pentest-context.jsonjson{ "signup_audit": { "timestamp": "...", "signup_open": true, "rate_limit": { ... }, "findings": [ ... ] } } -
Log to:
.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 -
If files don't exist, create them before writing.
FAILURE TO UPDATE CONTEXT FILES IS NOT ACCEPTABLE.
-
更新记录结果:
.sb-pentest-context.jsonjson{ "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 -
如果文件不存在,在写入前先创建。
未更新上下文文件的行为是不被接受的。
MANDATORY: Evidence Collection
MANDATORY: Evidence Collection
📁 Evidence Directory:
.sb-pentest-evidence/05-auth-audit/signup-tests/📁 证据目录:
.sb-pentest-evidence/05-auth-audit/signup-tests/Evidence Files to Create
需要创建的证据文件
| File | Content |
|---|---|
| Signup availability test |
| Weak password acceptance test |
| Disposable email test |
| Rate limiting test |
| 文件 | 内容 |
|---|---|
| 注册可用性测试结果 |
| 弱密码接受测试结果 |
| 临时邮箱测试结果 |
| 速率限制测试结果 |
Evidence Format
证据格式
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": "test@example.com", "password": "123456"},
"curl_command": "curl -X POST '$URL/auth/v1/signup' -H 'apikey: $ANON_KEY' -H 'Content-Type: application/json' -d '{\"email\": \"test@example.com\", \"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": "test@mailinator.com", "password": "Test123456!"}
},
"response": {
"status": 200,
"message": "User created"
},
"result": "VULNERABLE",
"impact": "Disposable emails not blocked"
}
]
}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": "test@example.com", "password": "123456"},
"curl_command": "curl -X POST '$URL/auth/v1/signup' -H 'apikey: $ANON_KEY' -H 'Content-Type: application/json' -d '{\"email\": \"test@example.com\", \"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": "test@mailinator.com", "password": "Test123456!"}
},
"response": {
"status": 200,
"message": "User created"
},
"result": "VULNERABLE",
"impact": "Disposable emails not blocked"
}
]
}Related Skills
相关技能
- — Full auth configuration
supabase-audit-auth-config - — User enumeration testing
supabase-audit-auth-users - — Protect user data with RLS
supabase-audit-rls
- — 完整身份验证配置审计
supabase-audit-auth-config - — 用户枚举测试
supabase-audit-auth-users - — 使用RLS保护用户数据
supabase-audit-rls