0

New to Pg from MS SQL side where to restrict access simply grant EXE permission to Functions and SPs. So created a user/role, set its search_path to a dedicated schema of a database, grant EXECUTE ON ALL FUNCTIONS IN SCHEMA myschema. Tried execute a function got

permission denied for schema myschema

Ok, grant usage on schema myschema to role. The function does a select ... from mytable so now

permission denied for table mytable

To grant SELECT on my table? Wait, purpose of this function is to restrict the role from exploring tables.

1
  • Do you expect the code inside the function to run with different permissions than those of the caller? Then you'll have to use SECURITY DEFINER. Commented Feb 26, 2021 at 0:40

1 Answer 1

3

Your situation is: User a owns a table mytable in a schema myschema. User b initially has no permissions on either. Now you want to allow b limited access to mytable. Granting SELECT on the table would be too much — you want to grant access only through a special function myfunction.

Then you need a function that does not run with the permissions of the caller (SECURITY INVOKER), which would be the default, but with the permissions of the function owner (SECURITY DEFINER). Then user a should run:

CREATE FUNCTION public.read_mytable(...) RETURNS ...
   LANGUAGE ...
   /* runs with the privileges of the owner */
   SECURITY DEFINER
   /* important: force "search_path" to a fixed order */
   SET search_path = pg_catalog,pg_temp
AS $$...$$;

/* by default, everybody can execute a function */
REVOKE EXECUTE ON FUNCTION public.read_mytable FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.read_mytable TO b;

Note that I created the function in schema public, to which b has access (don't forget to REVOKE CREATE ON SCHEMA public FROM PUBLIC;!).

Setting a search_path for user b is not enough, since this can always be changed dynamically with the SET command. You don't want b to run a privilege escalation attack.

Sign up to request clarification or add additional context in comments.

3 Comments

Excellent, I'm able to resolve it now without pg_temp in the path. What's the benefit of having it?
This is a good article. Wouldn't it be great to change default pg behavior every new funct/sp is granted EXE to public to be explicit permission grant like MS SQL or Oracle? Also REVOKE CREATE ON SCHEMA public FROM PUBLIC; is the default? Last question, any impact if I drop public schema?
That is just the standard order. You can set search_path empty with the same effect. The default settings are still there for compatiblity reasons, although efforts for public are underway. You can drop the public schema, but then you might need another place for extension objects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.