VibeGuard
Guides

SECURITY DEFINER views and functions that bypass RLS

A view created with SECURITY DEFINER executes with its owner's privileges. If the owner is a superuser or the table owner, the view returns rows the caller's policies would have denied — and it is reachable through PostgREST like any other relation.

The same applies to a SECURITY DEFINER function granted to `anon` or `authenticated`: it is an RLS bypass with a public entry point.

VibeGuard does not detect this yet. This guide gives you the catalog queries to check it yourself. The nine rules that do ship are listed on the rules index.

Finding SECURITY DEFINER views

Postgres 15 added `security_invoker` on views. A view without it, owned by a privileged role, runs as the definer.

SELECT n.nspname AS schema, c.relname AS view, pg_get_userbyid(c.relowner) AS owner
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'v'
  AND n.nspname NOT IN ('pg_catalog', 'information_schema')
  AND COALESCE(
        (SELECT option_value
           FROM pg_options_to_table(c.reloptions)
          WHERE option_name = 'security_invoker'),
        'false') = 'false';

Finding anon-callable SECURITY DEFINER functions

A function with `prosecdef = true` that `anon` can execute is callable by anyone holding your public key.

SELECT n.nspname AS schema, p.proname AS function
FROM pg_catalog.pg_proc p
JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
WHERE p.prosecdef
  AND n.nspname NOT IN ('pg_catalog', 'information_schema', 'extensions')
  AND has_function_privilege('anon', p.oid, 'EXECUTE');

Fixing them

For views on Postgres 15 and later, `ALTER VIEW ... SET (security_invoker = true)` makes the view respect the caller's policies.

For functions, either drop SECURITY DEFINER, or `REVOKE EXECUTE ... FROM anon` and keep it server-side. If it genuinely needs elevated privileges, it should not be reachable from a public key.

ALTER VIEW public.your_view SET (security_invoker = true);
REVOKE EXECUTE ON FUNCTION public.your_function FROM anon;

Frequently asked

Does VibeGuard detect this automatically?
Not yet. The nine shipped rules cover RLS state, policy correctness, storage exposure, index coverage and credential leakage. SECURITY DEFINER analysis is not among them, and this page exists to give you the queries rather than to imply a check that does not run.
Is the Supabase advisor better here?
For this specific check, yes — it flags SECURITY DEFINER views. Use it alongside, and use the queries above between advisor runs.

Check your project in about ten seconds

Paste a URL. No signup, no writes, nothing stored.

Run the free audit
supabase security advisor security definer viewsecurity definer view bypass rlsanon callable security definer function supabase