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.json IMMEDIATELY after each test completed
-
Log to .sb-pentest-audit.log BEFORE 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:
- Increase minimum length to 8+ characters
- Consider password strength requirements
- 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:
- Enable email confirmation
- Strengthen password policy
- Consider disposable email blocking
- 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.json with 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 configuration
-
supabase-audit-auth-users β User enumeration testing
-
supabase-audit-rls β Protect user data with RLS