supabase-js
supabase-js copied to clipboard
Extremely dangerous bug: Partial .rpc(...) execution when client is called from Next14 Server Actions. Breaks ACID guarantee.
Bug report
- [x] I confirm this is a bug with Supabase, not with my own application.
- [x] I confirm I have searched the Docs, GitHub Discussions, and Discord.
Describe the bug
A RPC call that only partially runs when called from a server action.
To Reproduce
I have a form that takes in two values: id
and value
, then calls the server action update
defined below.
Server action file
"use server":
import {createClient} from @supabase/supabase-js
const admin = createClient(supabaseUrl, supabaseServiceRoleKey);
export async function update(id: string, value: number) {
const { data, error } = await admin.rpc("update", {
id: id,
value: value,
});
return data
}
Table and Stored Procedure
create table users (
id uuid references auth.users not null primary key,
balance numeric default 0 not null
);
alter table users enable row level security;
create policy "Can view own user data." on users for select using (auth.uid() = id);
create or replace function public.update(id uuid, value numeric)
returns numeric as $$
declare
valid_value numeric;
begin
select least(value, balance) into valid_value
from users
where id = id;
update users
set balance = balance - valid_value
where id = id;
return valid_value;
end;
$$ language plpgsql security definer;
Think of this as a deposit withdrawal. What happens?
- rpc call succeeds with the correct value of
valid_value
returned. No error. - The
update
clause of the stored procedure does not run, so the balance is not updated for the withdrawal.
This is not an RLS failure. I turned off RLS entirely for the users
table and problem persists. The problem disappears when the Server Action block is moved to an API route and called from an API invocation.
Expected behavior
RPC runs entirely or not at all. In this case, RPC should always run, regardless of RLS, given the service_role key.
System information
- OS: MacOs
- Browser (if applies) Chrome
- Version of supabase-js: 2.23.0
- Version of Nextjs: 14.0.4
Additional context
Add any other context about the problem here.