MP099CRITICALFree
warn-security-definer-search-path
What It Detects
SECURITY DEFINER function without a pinned search_path lets the caller control name resolution inside a privileged body.
Why It's Dangerous
SECURITY DEFINER runs the body with the privileges of the function's owner rather than the caller's, and search_path decides what every unqualified name in that body resolves to. Leave it unpinned and the caller supplies it — the caller being precisely the person who does not have the owner's privileges. Creating a schema with a shadowing table and putting it first in search_path redirects the function's writes, with the owner's rights. EXECUTE on new functions is granted to PUBLIC by default, so that is usually everyone.
Bad Example
CREATE FUNCTION promote_user(uid int) RETURNS void AS $$ UPDATE users SET role = 'admin' WHERE id = uid; $$ LANGUAGE sql SECURITY DEFINER; -- Caller decides which "users" this writes to
Good Example
CREATE FUNCTION promote_user(uid int) RETURNS void AS $$ UPDATE public.users SET role = 'admin' WHERE id = uid; $$ LANGUAGE sql SECURITY DEFINER SET search_path = pg_catalog, public;
Configuration
Disable this rule:
# .migrationpilotrc.yml rules: MP099: false
Or change its severity:
# .migrationpilotrc.yml
rules:
MP099:
severity: warning