Skip to content

Supabase auth endpoints bypass our custom security #49

@mazeincoding

Description

@mazeincoding

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions