-
Notifications
You must be signed in to change notification settings - Fork 6
Description
This applies for a lot of actions (sign in, delete user, etc) but for example, we have an API endpoint to sign in users. This isn't just doing a simple Supabase call - it's getting the user's device, storing it for tracking, checking for unknown devices/2FA requirements, logging in the future and more. But any attacker could just open the browser console and run:
const { data, error } = await supabase.auth.signInWithPassword({
email: 'example@email.com',
password: 'example-password',
})Yes, it's really that easy. All they need is:
- anon key (this is publicly accessible)
- supabase project URL (also public)
Even if we:
- make our middleware log out users without a valid device session (what they don't get without using our API endpoint)
- add security checks for all actions
- make our API routes super secure
A user can STILL do pretty much any action Supabase allows. An attacker doesn't need to use our API endpoint to disable 2FA for example (which has security checks, logging in the future) - they can just:
const { data: factors } = await supabase.auth.mfa.listFactors();
await supabase.auth.mfa.unenroll({ factorId: factors[0]?.id });...and bypass all these things. So even if our middleware logs out users with no device session and our API endpoints has all those fancy checks, they can still some things.
Luckily, Supabase's got brain for some things. Like, that public anon key can't delete a user. Only the service role key can do that, but that's also pretty much the only thing we have control over (which is pretty bad, we don't even have control over our own security)
const { data: factors } = await supabase.auth.mfa.listFactors();
await supabase.auth.mfa.unenroll({ factorId: factors[0]?.id });Logging out other devices? Anon key can't do that here because that's our custom feature, something Supabase can't control.
But it's still pretty bad and needs a fix.