T05 · Unauthorized Access and Privilege Escalation
- Location
references/playwright-recipes.md:130- Finding
Production customer passwords can be destructively overwritten during testing
- Content
View full analysis
l.includes('=')) .map(l => { const i = l.indexOf('='); return [l.slice(0, i), l.slice(i + 1)]; }) ); const USER_ID = '...'; const TEMP_PASS = 'temp-' + Date.now(); await fetch(`${cred.SUPABASE_URL}/auth/v1/admin/users/${USER_ID}`, { method: 'PUT', headers: { apikey: cred.SUPABASE_SERVICE_ROLE_KEY, Authorization: 'Bearer ' + cred.SUPABASE_SERVICE_ROLE_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ password: TEMP_PASS }), }); // ... do test work ... // IMPORTANT: scramble the password back so the test password isn't usable. await fetch(`${cred.SUPABASE_URL}/auth/v1/admin/users/${USER_ID}`, { method: 'PUT', headers: { apikey: cred.SUPABASE_SERVICE_ROLE_KEY, Authorization: 'Bearer ' + cred.SUPABASE_SERVICE_ROLE_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ password: 'reset-' + Math.random().toString(36) }), }); ``` ### Technical Analysis The recipe uses the production Supabase service-role key to replace the password of an arbitrary user identified by `USER_ID`. A service-role key bypasses normal row-level authorization and can administer the entire Supabase project. The purported cleanup does not restore the original password. It changes the password to another unknown value, permanently invalidating the customer's original credentials. In addition, the initial temporary password is based only on the current timestamp and is not cryptographically random. If execution terminates before the second request, that predictable password can remain active. Mutating a real customer's cr ...[truncated 1172 chars]- Remediation
View remediation
