supabase-audit-auth-signup
npx skills add https://github.com/yoanbernabeu/supabase-pentest-skills --skill supabase-audit-auth-signup
Agent 安装分布
Skill 文档
Signup Flow Audit
ð´ CRITICAL: PROGRESSIVE FILE UPDATES REQUIRED
You MUST write to context files AS YOU GO, not just at the end.
- Write to
.sb-pentest-context.jsonIMMEDIATELY after each test completed- Log to
.sb-pentest-audit.logBEFORE and AFTER each test- 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.
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)
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 project
Check Specific Aspects
Test if disposable emails are blocked for signup
Output 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
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Test Details
Disposable Email Detection
Common disposable email domains tested:
- 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
Rate Limit Testing
Attempt 1: 200 OK
Attempt 2: 200 OK
Attempt 3: 200 OK
Attempt 4: 429 Too Many Requests
Context Output
{
"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
// 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');
}
Strengthen Password Requirements
// 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;
}
Prevent Email Enumeration
// 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' };
}
Restrict Signup
If signup should be invite-only:
// 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
});
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.
Required Actions (Progressive)
-
Update
.sb-pentest-context.jsonwith results:{ "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.
MANDATORY: Evidence Collection
ð Evidence Directory: .sb-pentest-evidence/05-auth-audit/signup-tests/
Evidence Files to Create
| File | Content |
|---|---|
signup-tests/open-signup.json |
Signup availability test |
signup-tests/weak-password.json |
Weak password acceptance test |
signup-tests/disposable-email.json |
Disposable email test |
signup-tests/rate-limit.json |
Rate limiting test |
Evidence Format
{
"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
supabase-audit-auth-configâ Full auth configurationsupabase-audit-auth-usersâ User enumeration testingsupabase-audit-rlsâ Protect user data with RLS