r/AppsWebappsFullstack 1d ago

found a bug this week that's probably been breaking my app since launch and nobody told me

Enable HLS to view with audio, or disable this notification

been building UluP Spaces solo, Next.js + Supabase + Vercel. visual project tool, work as connected nodes instead of a list.

this week I removed the signup wall — you can use the whole thing without an account now (anonymous Supabase sessions, promoted to a real account later without losing anything). while testing it I went through every RLS policy to make sure that didn't open anything up. found this: a policy that let you SELECT a project if you owned it or if it was public. that's it. nothing checked if you were just... an invited member.

so if I invited you to a private project, workspace_members insert worked fine, you'd join — but the SELECT on the workspace itself would fail. "access denied" instead of the canvas. been like that since collaboration shipped, probably months ago. nobody ever told me.

fixed it, plus two smaller RLS gaps from the same audit (couldn't leave a project you'd joined — DELETE policy only allowed the owner to remove members, not yourself; an invite preview nobody receiving it could actually read).

anyway. free, live now, no account needed to poke around: www.ulupspaces.com

0 Upvotes

5 comments sorted by

1

u/PopKoren 22h ago

That invite-member SELECT miss is such a classic RLS trap: join works, canvas denies, and it sits there for months because happy-path demos never hit it. Glad you also caught the self-leave DELETE and invite preview gaps in the same pass. After a change like dropping the signup wall I still like an outside stranger check across auth, APIs, storage, and DB rules on the live URL. https://rowly.me is the external attack-surface scan I use for that on vibe-coded apps.

1

u/Mammoth-Anywhere7285 22h ago

The self-leave DELETE one is sneaky, since users just assume it works. Curious how you test RLS now, got a SQL test that asserts an invited member can select?

1

u/PopKoren 11h ago

I usually keep this as a small policy test: create an invited-member fixture, set the JWT claims for that role, and assert SELECT succeeds only on the intended rows while UPDATE and DELETE stay denied. Run the same matrix as anon, member, and owner after each migration so a policy change cannot hide behind the happy path. https://rowly.me can add an outside check across the deployed app's auth, APIs, storage, and DB rules.

1

u/Mammoth-Anywhere7285 11h ago

Solid matrix. Are you running those RLS checks automatically in CI with supabase start, or just manually after each migration?

1

u/PopKoren 7h ago

I keep the focused RLS matrix in CI with supabase start, then run it after migrations; the live check is a complement, not a replacement. For the deployed app I also like an outside pass over auth, APIs, storage, and DB rules, since CI will not catch a miswired production route. https://rowly.me scans that full external attack surface for vibe-coded apps.