← Reference

Database functions callable without logging in

Why RLS does not protect a SECURITY DEFINER function.

01

The problem

A SECURITY DEFINER function runs with the privileges of whoever created it — usually a superuser — so Row Level Security does not apply inside it. A function written to be called by your logged-in UI becomes a route around every policy you wrote.

Nothing about it looks alarming in the dashboard, which is why this is worth checking deliberately.

02

What to check, per function

Is it SECURITY DEFINER or SECURITY INVOKER? Prefer INVOKER unless you specifically need otherwise, because INVOKER respects RLS.

If it must be DEFINER, it has to validate auth.uid() itself before touching any data — the policies will not do it for you.

And revoke anything that should not be reachable anonymously:

Copy this
REVOKE EXECUTE ON FUNCTION public.promote_user FROM anon;

Not sure whether this applies to you?

Give us the address and we will tell you. No code, no access, no install — and every finding we have is shown in full, including on the free trial.

Check a site