S
Supabase3mo ago
eric44

Is there a point to server side validation with supabase

Im using nextJS and there technically is a supabase client in the browser. if someone can hack and get access to it in devTools they can upsert to their own row. RLS stops them from uploading elsewhere but to their own row theytechnically can do anyhting. Which makes me wonder if there is a point to server side validation? Furthermore how do you stop someone from technically upserting their own role in a user_roles table?
34 Replies
garyaustin
garyaustin3mo ago
You don't allow them RLS to insert/update user roles, points, groups, account numbers etc. Those are set either from server code, edge functions bypassing RLS or with an RLS for an admin type role. You can't trust any data from the user from a browser to either Supabase REST or your own API. They can't modify the JWT is why it is considered safe.
eric44
eric44OP3mo ago
so... how does one submit a form? i have a edit profile form. they can edit their row. how should i set their role? i set there role when they first join and fill out the profile form the first time
garyaustin
garyaustin3mo ago
Then you would move the things they should not modify to another table is the easiest way. So a profile table they can change and a secure_properties or secure_profile table they can't modify. You can also use update triggers to block modifying certain columns. There is also postgres column privileges but it is hard to use and not supported with SB migrations.
eric44
eric44OP3mo ago
so what do i do to edit a row from nextjs if i dont give them any access
garyaustin
garyaustin3mo ago
You either have an admin user and add some sort of role system to the tables or jwt custom claims or you use service_role to bypass RLS.
eric44
eric44OP3mo ago
ohhh. there is an adminClient... am i suppose ot be using that for upserts!?
garyaustin
garyaustin3mo ago
It all depends on what you are doing.
Users can upsert/update/insert/delete stuff that is not secure and only messes them up if the "cheat". You have RLS to allow or not. An adminClient with service_role can do those operations and bypass any RLS restrictions. Then you must make sure you enforce everything in your server side code including filters to make sure only their row is changed. You have their user id to do that.
eric44
eric44OP3mo ago
ok! why didnt the docs talk about this when i was reading it for nextjs. part of me feels like locking all tables down and using server routes to do all the work with admin client
garyaustin
garyaustin3mo ago
You can block all the table with no RLS and do service_role from the server. Some users do that.
eric44
eric44OP3mo ago
yeah sounds easier and puts me in contrll its what im used to form my wordpress days i do have nuances hwere i want people to be able to see parts of a profile but not the whole thing its i had to split the table into 3 and its annoying
garyaustin
garyaustin3mo ago
Supabase started out in the days of everything going serverless like firebase. So most stuff is designed for that. Then next.js got popular and a shift occurred to do server side and client. Some just do server side. Sort of back to PHP days if you will.
eric44
eric44OP3mo ago
my words are not spelling sell today serverless is hard i guess. not full control and scary and RLS can only do so much
garyaustin
garyaustin3mo ago
Everything is a tradeoff.
eric44
eric44OP3mo ago
well nextjs has server side and it feels safer
garyaustin
garyaustin3mo ago
Then go that way if you are comfortable with it.
eric44
eric44OP3mo ago
ok ill play around and decide i dont mind most selects but some are difficutl i had profiles. then i had a column that was only for certain roles to be able to see then i had a cool idea where the user can share half of their profile. but if a user can hack the browserclient they can query and get the full profile its prob never gonna happen and my site is for niche users who arent that savvy but u never know!
garyaustin
garyaustin3mo ago
Lots of ways to deal with it... from a client too. You can block the tables and use views or rpc calls. But if you are comfortable with serverside then that is fine too. Some don't release their anon key at all. Does make storage a bit more difficult and realtime won't work serverside easily but just depends on what you are doing.
eric44
eric44OP3mo ago
well hard to not release the anon key when i have the browser client doing fetching client side
garyaustin
garyaustin3mo ago
I'm saying some do everything server side. So browser does not access supabase.
eric44
eric44OP3mo ago
i hear. so if i never import the supabase client in client side i guess its never bundled in? i never know with this stuff... i need to get the service key for admin clinet where do i find or make that
garyaustin
garyaustin3mo ago
?
eric44
eric44OP3mo ago
to make a admin clinet for supabase that gets around RLS i need a key
garyaustin
garyaustin3mo ago
Yes. It is in your api key section of dashboard right below anon.
eric44
eric44OP3mo ago
found it. cool didnt know this even existed ill have to go over my schema and decide how to use it
eric44
eric44OP3mo ago
most tables i allow user to just see their onw stuff so it was simple. it was when i was dealing with users seeing others stuff that things got hard
garyaustin
garyaustin3mo ago
I'm out for the night. Good luck
eric44
eric44OP3mo ago
thank you for all your help! good night going to sleep here too bye! morning. im thinking it through and for me its mostly the SELECT that i need via admin priveleges cause i want to hide/show speicifc columns and doing that with an admin client on server side seems to be the besrt way for me. I can make a view but i dont know sql as well as i know javascript anmd nextjs.
garyaustin
garyaustin3mo ago
Unless you want to split into tables, views or rpc calls overriding RLS would be the way client side. Splitting tables is the safest as it is clear what each is for. So seems like you are still pointing yourself to serverside only.
eric44
eric44OP3mo ago
yeah because i have a profile table and based on users role we show parts of the table. i tried splitting the table but it doesnt wokr when i need parts of both tablesdepending on role. it was getting messy i think its easier to just remove select entirely and use server side for Select with admin proveleges but i will keep RLS upsert for current user on their row so its a hybrid approach
garyaustin
garyaustin3mo ago
Normally when you split the table you use a view to join them or only fetch the part you need for an operation.
Also you use a foreign key to link all the users tables to the main profile table so that you can just join them in the REST API calls. But all complexity for sure. I've seen CMS's like Drupal where every "column" is a separate table...
eric44
eric44OP3mo ago
the profile table would need to be split into 3. the public table for everyones viewing. the second table for even more viewing. and then the third table for speicfic signed in roles. it seemed heavy and connecting them was a headache even with a view i would have to do a lot of work in supabase to lock down the select and make functions to get only the parts i wanted.... im better at server side code written in my editor than i am tinkering in supabase
garyaustin
garyaustin3mo ago
I'm not arguing to persuade you. Just saying how it is done in may cases. You can handle it all server side in logic.
eric44
eric44OP3mo ago
yeah i understand. see i have a slug column. which gets yoyu the entire profile. we do a select and get the slug and get the entire row. Then there was 2 columns we didnt want regular users seeing. so we broke those off into a separate table. we gave it RLS so that only speicifc users can see those. then I came up with the idea for a "limited view" which allows you to share a limited view slug. different from the main slug. which sleects a few of the columns from the profile. but for that we would have to split those off into yet another table. And wherew would this limited view slug live? on that 3rd table? and if smeone now wants the full profile using the real slug i have to get the main tables row. trhen join the other tables... it becomes hard sounsd easier to just have a serverside file that can decide what to SELECT and show that based on user and keep it to one nice table see how confusing that was just to write? lol

Did you find this page helpful?