Skip to content

fix(0028,0029): only report functions exposed by PostgREST - #213

Open
anh-nguyenn wants to merge 1 commit into
supabase:mainfrom
anh-nguyenn:fix/0028-0029-rpc-exposure
Open

anh-nguyenn wants to merge 1 commit into
supabase:mainfrom
anh-nguyenn:fix/0028-0029-rpc-exposure

Conversation

@anh-nguyenn

Copy link
Copy Markdown

Fixes #212.

Problem

Lints 0028_anon_security_definer_function_executable and 0029_authenticated_security_definer_function_executable matched every pg_proc row with prosecdef = true and EXECUTE for the role. That includes procedures (prokind = 'p') and trigger functions (prorettype = 'trigger'::regtype), which PostgREST does not expose as /rpc endpoints. The findings therefore claimed a route that does not exist.

PostgREST's schema-cache function query (funcsSqlQuery in PostgREST/SchemaCache.hs) filters with prokind = 'f' and t.oid <> 'trigger'::regtype, so the lints should apply the same constraints.

Reproduction (reported before the change):

set pgrst.db_schemas = 'public';

create procedure public.secdef_proc() language sql security definer
  as $$ select 1 $$;

create function public.secdef_trigger() returns trigger
  language plpgsql security definer
  as $$ begin return new; end $$;

select name, metadata->>'name' from lint."0028_anon_security_definer_function_executable";
-- reports secdef_proc() and secdef_trigger()

Fix

Both lints now additionally require:

and p.prokind = 'f'
and p.prorettype <> 'pg_catalog.trigger'::regtype

splinter.sql was regenerated with python bin/compile.py.

Tests

Added negative cases to test/sql/0028_* and test/sql/0029_* for a SECURITY DEFINER procedure and a SECURITY DEFINER trigger function, and updated the expected output. Before the fix those cases produced one and two findings respectively; after the fix both return 0 rows.

Validation (PostgreSQL 15.19, ./bin/installcheck):

  • 0028_anon_security_definer_function_executable — pass
  • 0029_authenticated_security_definer_function_executable — pass
  • full suite — 27 of 29 pass; 0026/0027 fail in my local environment because the pg_graphql extension is not installed there (they fail identically on unmodified main)
  • python bin/check_lints.py — all 29 lints registered

These lints match every SECURITY DEFINER pg_proc entry executable by
the role, including procedures and trigger functions. PostgREST does
not expose either: its schema cache selects prokind = 'f' and excludes
functions returning trigger, so the findings claim an /rpc route that
does not exist.

Filter both lints the same way and add regression cases for a
SECURITY DEFINER procedure and a SECURITY DEFINER trigger function.
@anh-nguyenn
anh-nguyenn requested a review from a team as a code owner November 7, 2026 10:16

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lints 0028/0029 report procedures and trigger functions as callable via PostgREST /rpc

1 participant