mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
Loading a truncated cell's full value from the inline grid editors or the row side-panel editors called `getCellValue` without `roleImpersonationState`, so the fetch ran with full DB privileges instead of the role selected in **View as role** — leaking values RLS would deny. Same class of bug #46442 fixed for row copy/export; the mutation already accepted the state, these call sites just weren't passing it. **Changed:** - Pass `roleImpersonationState` into `getCellValue` in all 4 truncated-cell loaders (inline grid Text/Json editors + row side-panel Text/Json editors), mirroring the existing `Header.tsx` pattern **Added:** - MSW component test on the row side-panel `TextEditor` asserting the cell-value SQL is wrapped with `set local role` when impersonation is active, and not wrapped when it isn't ## To test Note: if the impersonated role can't select the row at all (e.g. force RLS with no policy), the main grid correctly shows 0 rows under **View as role**, so the "Load full value" button is never reachable — you can't exercise this path that way. Use a row the role *can* see and verify the request is role-wrapped: - Create a table with a text value long enough to be truncated in the grid (>16KB), with RLS enabled and an anon-visible row: ```sql create table public.secrets (id int primary key, secret text); alter table public.secrets enable row level security; alter table public.secrets force row level security; create policy "anon can read" on public.secrets for select to anon using (true); insert into public.secrets values (1, repeat('a', 20000)); ``` - In the Table Editor, set **View as role → anon** — the row should be visible with the `secret` cell truncated - With the network tab open, load the full value via each path: double-click the cell (inline editor) and the row side panel's expand editor → "Load full text data" (a `jsonb` column exercises the two JSON editor paths the same way) - The `pg-meta` query request body should start with `set_config('role', 'anon', true)` + anon JWT claims before the `select secret …`. Before this fix it was a bare unwrapped `select secret from public.secrets where id = 1;` - Drop the policy and confirm the grid shows 0 records under anon (denial still applies at the grid level); switch back to the default role and confirm the full value still loads normally with no wrapper Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>