is it a security issue that All the supabase requests are coming directly from client instead of the backend ( vercel ) ?
from ghodawalaaman@programming.dev to programming@programming.dev on 13 Mar 07:10
https://programming.dev/post/47123505

Hello,

recently I was working on a project entirely made by AI. at first it looked plausible but as I dig deeper into the code I found out ton of security issues. we solved the security issues one by one. ( thankfully the site isn’t released yet and only have beta testing users )

my question is that is it considered a security issue if I let the client ( browser ) make the supabase api call instead of routing those requests through the backend ( vercel ) even when I have made policies that prevents unauthorized users from submitting INSERT queries however I am still not sure if this is enough.

one thing that comes in my mind is that any authorized user can just spam the database and fill it with junk data but I think I can just ban that user and delete all the junk data relatively easily using a SQL query?

the thing is that I don’t want to refactor AI code and make it “use server” instead of “use client”. since I have to make a ton of changes and I am still learning Nextjs. ( thinking about using AI to fix AI code but I don’t think it will work and don’t want more AI slop in the codebase )

any suggestions are appreciated!

#programming

threaded - newest

tyler@programming.dev on 13 Mar 07:27 next collapse

What policies are preventing users from inserting data? If you are asking this question then you very likely should not be doing what you’re doing. There are ways to do it safely, but it’s for very very specific circumstances, with very very specific security setups.

ghodawalaaman@programming.dev on 13 Mar 07:41 collapse

What policies are preventing users from inserting data? okay, I just got confused there for a bit actually what’s happening is that I have created a policy on SELECT to prevent other users from accessing data of other users and it looks something like auth.uid() = user_id. iirc the policy to prevent INSERT looks something like this: auth.role() = ‘authenticated’::text() so yeah only authenticated users can insert data but that doesn’t guaranty that client/user/browser will insert correct data.

If you are asking this question then you very likely should not be doing what you’re doing. yes, I know that’s why I am asking for suggestions, I don’t have much experience in either supabase or Nextjs but I am learning :)

There are ways to do it safely, but it’s for very very specific circumstances, with very very specific security setups. okay, so what do you suggest I should do. I can’t just shove more policies into the supabase to make it secure I think so the only way to make it secure is to have the server ( vercel ) do all the supabase calls and don’t share the supabase url so that the client can’t just query supabase. but again the reason I am not doing this is that it will require a very big refactor throughout the codebase. ( which I am terrified of T.T )

tyler@programming.dev on 13 Mar 07:51 collapse

I don’t really know jack about supabase, but what I’m getting at is that authentication is tied to a user store somewhere. So your user authenticates, they do so against something. Either your server or your database. If they do it against your database, then fine, but how did that user get created? How are they making the connection? How are your policies applied for that user? What keeps a user from spamming your database with login attempts to guess other users or your root db user?

If your users have to authenticate against a server you don’t have to worry about the database. You can use a authentication library for your language and you’re good to go in most cases. You can then also scale your database separately.

Maybe supabase is designed for this, idk, but I personally wouldn’t ever design a site that way, unless it was a very very niche circumstance.

HelloRoot@lemy.lol on 13 Mar 07:35 next collapse

This is fundamentally how Firebase etc. is meant to work: the client talks directly to the database, and security rules gate access. You don’t need your own backend in between.

As for the spam issue, you’re right that supabase can’t do it (firebase can btw.)

github.com/orgs/supabase/discussions/36512

github.com/orgs/supabase/discussions/19493

Not sure what the best approach is, but for me it just sounds like supabase is not ready for real world production.

HelloRoot@lemy.lol on 13 Mar 08:30 collapse

ps:

trailbase seems to do user rate limiting by ip through a reverse proxy. I’m sure the same can be done for supabase. trailbase.io/documentation/production/#reverse-pr…

nous@programming.dev on 13 Mar 08:55 next collapse

Yes it is a security issue. But almost everything is. You can make it secure enough with the right policies. However it overall increases the attack surface of your application and has a greater chance that you missed something or miss configured the policies. So many firebase apps have been hacked because of miss configured access to the database.

So it puts more work on you to get things right.

kibiz0r@midwest.social on 13 Mar 11:58 collapse

As always: it depends

My first concern with exposing a DB to an authenticated client is incomplete state transitions. Often, a user interaction requires updating multiple DB entities in order to complete properly. Clients can die at any point, but servers should (hopefully) stay alive through one entire request and ensure that the DB goes from one complete valid state to the next.

My second would be: just because you verify that the user is allowed to modify a given record doesn’t mean that all possible DB-level modifications are valid at an application level. That’s where resource-level security is insufficient. Security gaps often consist of having legitimate access to a resource but performing unexpected actions against it.

I don’t know anything about supabase specifically, so I can’t guide you there. But those are the big two security (and data integrity) concerns I’d never stop worrying about in a direct-to-DB scenario.