Authenticated User 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 Log to .sb-pentest-audit.log BEFORE and AFTER each action 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 creates a test user (with explicit permission) to compare authenticated vs anonymous access and detect IDOR vulnerabilities. โ ๏ธ IMPORTANT: User Consent Required โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ ๐ USER CREATION CONSENT REQUIRED โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ โ โ โ This skill will CREATE A TEST USER in your Supabase project. โ โ โ โ The user will be created with: โ โ โข Email: pentest-[random]@security-audit.local โ โ โข Password: Strong random password (32+ chars) โ โ โข Purpose: Testing authenticated access vs anonymous โ โ โ โ At the end of the audit, you will be asked if you want to โ โ DELETE the test user (recommended). โ โ โ โ Do you authorize the creation of a test user? โ โ Type "yes, create test user" to proceed. โ โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ DO NOT proceed without explicit user consent. When to Use This Skill After completing anonymous access tests To detect IDOR (Insecure Direct Object Reference) vulnerabilities To test cross-user data access To verify RLS policies work for authenticated users To find privilege escalation issues Prerequisites Signup must be open (or use invite flow) Anon key available Anonymous audit completed (recommended) Why Authenticated Testing Matters Many vulnerabilities only appear with authentication: Vulnerability Anonymous Authenticated RLS bypass (no RLS) โ Detectable โ Detectable IDOR โ Not visible โ Only visible Cross-user access โ Not visible โ Only visible Privilege escalation โ Not visible โ Only visible Overly permissive RLS Partial โ Full detection Test User Creation Email Format pentest-[8-char-random]@security-audit.local Example: pentest-a7b3c9d2@security-audit.local Password Generation Strong password with: 32+ characters Uppercase, lowercase, numbers, symbols Cryptographically random Example: Xk9$mP2#vL5@nQ8&jR4*wY7!hT3%bU6^ The password is displayed ONCE and saved to evidence. Tests Performed 1. User Creation & Login
Create user
curl -X POST " $SUPABASE_URL /auth/v1/signup" \ -H "apikey: $ANON_KEY " \ -H "Content-Type: application/json" \ -d '{"email": "pentest-xxx@security-audit.local", "password": "[STRONG_PASSWORD]"}'
Login and get JWT
curl -X POST " $SUPABASE_URL /auth/v1/token?grant_type=password" \ -H "apikey: $ANON_KEY " \ -H "Content-Type: application/json" \ -d '{"email": "pentest-xxx@security-audit.local", "password": "[STRONG_PASSWORD]"}' 2. Authenticated vs Anonymous Comparison For each table: Test Anonymous Authenticated Finding SELECT 0 rows 1,247 rows ๐ด Auth-only exposure Own data N/A Only own row โ RLS working Other users' data N/A All rows ๐ด Cross-user access 3. IDOR Testing
As test user, try to access other user's data
curl " $SUPABASE_URL /rest/v1/orders?user_id=eq.[OTHER_USER_ID]" \ -H "apikey: $ANON_KEY " \ -H "Authorization: Bearer [TEST_USER_JWT]"
If returns data: IDOR vulnerability!
- Cross-User Access
Get test user's ID from JWT
TEST_USER_ID
$( echo $JWT | jq -r '.sub' )
Try to access data belonging to a different user
curl " $SUPABASE_URL /rest/v1/profiles?id=neq. $TEST_USER_ID " \ -H "Authorization: Bearer [TEST_USER_JWT]"
If returns other users' profiles: Cross-user access!
- Storage with Authentication
Test authenticated storage access
curl " $SUPABASE_URL /storage/v1/object/list/documents" \ -H "apikey: $ANON_KEY " \ -H "Authorization: Bearer [TEST_USER_JWT]"
Compare with anonymous results
- Realtime with Authentication // Subscribe to table changes as authenticated user const channel = supabase . channel ( 'test' ) . on ( 'postgres_changes' , { event : '*' , schema : 'public' , table : 'orders' } , payload => console . log ( payload ) ) . subscribe ( ) // Does it receive OTHER users' order changes? Output Format โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ AUTHENTICATED USER AUDIT โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Test User Creation โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Status: โ User created successfully Test User Details: โโโ Email: pentest-a7b3c9d2@security-audit.local โโโ User ID: 550e8400-e29b-41d4-a716-446655440099 โโโ Password: [Saved to evidence - shown once] โโโ JWT obtained: โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Anonymous vs Authenticated Comparison โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Table: users โโโ Anonymous access: 0 rows โโโ Authenticated access: 1,247 rows โ ALL USERS! โโโ Status: ๐ด P0 - Data hidden from anon but exposed to any auth user Table: orders โโโ Anonymous access: 0 rows (blocked) โโโ Authenticated access: 1 row (own orders only) โโโ Status: โ RLS working correctly Table: profiles โโโ Anonymous access: 0 rows โโโ Authenticated access: 1,247 rows โ ALL PROFILES! โโโ Own profile only expected: โ NO โโโ Status: ๐ด P0 - Cross-user profile access โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ IDOR Testing โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Test: Access other user's orders by ID โโโ Request: GET /orders?user_id=eq.[other-user-id] โโโ Auth: Test user JWT โโโ Response: 200 OK - 15 orders returned โโโ Status: ๐ด P0 - IDOR VULNERABILITY Proof: curl "$URL/rest/v1/orders?user_id=eq.other-user-uuid" \ -H "Authorization: Bearer [test-user-jwt]"
Returns orders belonging to other-user-uuid!
Test: Access admin endpoints โโโ Request: GET /functions/v1/admin-panel โโโ Auth: Test user JWT (regular user) โโโ Response: 200 OK - Admin data returned! โโโ Status: ๐ด P0 - PRIVILEGE ESCALATION โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Storage with Authentication โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Bucket: documents โโโ Anonymous: โ 0 files (blocked) โโโ Authenticated: โ 523 files visible โ ALL USERS' FILES! โโโ Status: ๐ด P1 - Auth users see all documents Bucket: user-uploads โโโ Anonymous: โ 0 files โโโ Authenticated: 3 files (own files only) โโโ Status: โ RLS working correctly โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Summary โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ New Findings (Auth-only): โโโ ๐ด P0: users table - all users visible to any auth user โโโ ๐ด P0: profiles table - cross-user access โโโ ๐ด P0: IDOR in orders - can access any user's orders โโโ ๐ด P0: Privilege escalation in admin-panel โโโ ๐ P1: documents bucket - all files visible to auth users Comparison: โโโ Issues found (Anonymous): 3 โโโ Issues found (Authenticated): 8 โ 5 NEW ISSUES! โโโ Auth-only vulnerabilities: 5 Recommendation: These issues were NOT visible in anonymous testing! Always test with authenticated users. โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Cleanup โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ ๏ธ Test user still exists in database. Do you want to delete the test user? Email: pentest-a7b3c9d2@security-audit.local [This requires service_role key or manual deletion] โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Context Output { "authenticated_audit" : { "timestamp" : "2025-01-31T12:00:00Z" , "test_user" : { "email" : "pentest-a7b3c9d2@security-audit.local" , "user_id" : "550e8400-e29b-41d4-a716-446655440099" , "created_at" : "2025-01-31T12:00:00Z" , "deleted" : false } , "comparison" : { "tables" : { "users" : { "anon_access" : 0 , "auth_access" : 1247 , "expected_auth_access" : "own_row_only" , "severity" : "P0" , "finding" : "All users visible to any authenticated user" } , "orders" : { "anon_access" : 0 , "auth_access" : 1 , "expected_auth_access" : "own_rows_only" , "severity" : null , "finding" : "RLS working correctly" } } , "idor_tests" : [ { "test" : "access_other_user_orders" , "vulnerable" : true , "severity" : "P0" , "proof" : "curl command..." } ] , "privilege_escalation" : [ { "endpoint" : "/functions/v1/admin-panel" , "vulnerable" : true , "severity" : "P0" } ] } , "summary" : { "anon_issues" : 3 , "auth_issues" : 8 , "auth_only_issues" : 5 } } } RLS Policy Examples Correct: Users see only their own data -- This RLS policy is correct CREATE POLICY "Users see own data" ON users FOR SELECT USING ( auth . uid ( ) = id ) ; -- Result: -- Anonymous: 0 rows -- Authenticated: 1 row (own data) Incorrect: All authenticated users see everything -- This RLS policy is WRONG CREATE POLICY "Authenticated users see all" ON users FOR SELECT USING ( auth . role ( ) = 'authenticated' ) ; -- โ Too permissive! -- Result: -- Anonymous: 0 rows -- Authenticated: ALL rows โ VULNERABILITY! Correct fix: -- Fix: Add user ownership check CREATE POLICY "Users see own data" ON users FOR SELECT USING ( auth . uid ( ) = id ) ; -- โ Only own row Cleanup Options Option 1: Manual deletion (Dashboard) Supabase Dashboard โ Authentication โ Users โ Find test user โ Delete Option 2: Via service_role key (if available) curl -X DELETE " $SUPABASE_URL /auth/v1/admin/users/[USER_ID]" \ -H "apikey: $SERVICE_ROLE_KEY " \ -H "Authorization: Bearer $SERVICE_ROLE_KEY " Option 3: Leave for later The test user uses a non-functional email domain ( security-audit.local ) and cannot be used maliciously. MANDATORY: Evidence Collection ๐ Evidence Directory: .sb-pentest-evidence/05-auth-audit/authenticated-tests/ Evidence Files to Create File Content test-user-created.json Test user details (password saved securely) anon-vs-auth-comparison.json Side-by-side comparison idor-tests/[table].json IDOR test results privilege-escalation.json Privilege escalation tests Evidence Format { "evidence_id" : "AUTH-TEST-001" , "timestamp" : "2025-01-31T12:00:00Z" , "category" : "auth-audit" , "type" : "authenticated_testing" , "test_user" : { "email" : "pentest-a7b3c9d2@security-audit.local" , "user_id" : "550e8400-..." , "password" : "[STORED SECURELY - DO NOT COMMIT]" } , "comparison_test" : { "table" : "users" , "anonymous" : { "curl_command" : "curl '$URL/rest/v1/users' -H 'apikey: $ANON_KEY'" , "response_status" : 200 , "rows_returned" : 0 } , "authenticated" : { "curl_command" : "curl '$URL/rest/v1/users' -H 'apikey: $ANON_KEY' -H 'Authorization: Bearer $JWT'" , "response_status" : 200 , "rows_returned" : 1247 } , "finding" : { "severity" : "P0" , "issue" : "All users visible to any authenticated user" , "expected" : "Only own row should be visible" , "impact" : "Full user enumeration for any authenticated user" } } } Add to curl-commands.sh
=== AUTHENTICATED TESTING ===
NOTE: Replace [JWT] with test user's JWT
Compare anonymous vs authenticated access
curl -s " $SUPABASE_URL /rest/v1/users?select=&limit=5" -H "apikey: $ANON_KEY " curl -s " $SUPABASE_URL /rest/v1/users?select=&limit=5" -H "apikey: $ANON_KEY " -H "Authorization: Bearer [JWT]"
IDOR test - access other user's data
curl -s " $SUPABASE_URL /rest/v1/orders?user_id=eq.[OTHER_USER_ID]" \ -H "apikey: $ANON_KEY " \ -H "Authorization: Bearer [JWT]"
Cross-user profile access
curl -s " $SUPABASE_URL /rest/v1/profiles?id=neq.[TEST_USER_ID]" \ -H "apikey: $ANON_KEY " \ -H "Authorization: Bearer [JWT]" 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 user creation โ Log consent and action to .sb-pentest-audit.log After user created โ Immediately save user details to context and evidence After each comparison test โ Update .sb-pentest-context.json with results After each IDOR test โ Save evidence immediately This ensures that if the skill is interrupted, crashes, or times out, all findings up to that point are preserved. Required Actions (Progressive) Log user creation: [TIMESTAMP] [supabase-audit-authenticated] [CONSENT] User authorized test user creation [TIMESTAMP] [supabase-audit-authenticated] [CREATED] Test user pentest-xxx@security-audit.local Save test user to context immediately: { "authenticated_audit" : { "test_user" : { "email" : "..." , "user_id" : "..." , "created_at" : "..." } } } Log each finding as discovered: [TIMESTAMP] [supabase-audit-authenticated] [FINDING] P0: IDOR in orders table FAILURE TO UPDATE CONTEXT FILES PROGRESSIVELY IS NOT ACCEPTABLE.