Reputation: 613
I'm having trouble understanding privileges in PostgreSQL.
E.g. I have a web application with the user webapiuser
. This user is limited in the sense that it can only action the database through a function of some sort. That means no direct DB CRUD operations, only via functions created by the god postgres
user and only functions within its own domain. I've done all sorts of reading with many tutorials point to adding SECURITY DEFINER
to each function, but this allows the function to be executed by the function owner on behalf of the user which defeats the purpose in my understanding; I'm trying to lock down this sort of access after all.
I've already created a user with:
CREATE USER webapiuser WITH PASSWORD <password>;
And granted USAGE
to all schemas:
GRANT USAGE ON SCHEMA schemaA TO webapiuser;
GRANT USAGE ON SCHEMA schemaB TO webapiuser;
GRANT USAGE ON SCHEMA poublic TO webapiuser;
I've tried adding:
GRANT EXECUTE ON FUNCTION schemaA.func_myfunction() TO webapiuser;
But then I'm hit with permission denied for view view_my_view
. The function does select from this view so I guess the GRANT
command is working. I get a similar error permission denied for table my_table
if I execute a function that performs insert operations. How far down the privileges rabbit hole must I go to perform this seemingly simple task? And if I grant INSERT
, UPDATE
, DELETE
privileges to this user on these tables directly then that defeats the purpose.
Shouldn't granting the user EXECUTE
permissions on a function allow it to do anything within the scope of that function?
Upvotes: 1
Views: 1022
Reputation: 248215
Let me start by saying that it surprises me how many people think that it is the best way to use functions for data modification. Apart from the fact that PL/pgSQL function cache plans (which you can also have with prepared statements), I do not see the point.
You should on no account use superuser privileges for anything unless you absolutely have to, that is unnecessary and a security problem.
To describe my suggestion, take three (normal!) users a
, b
and c
:
a
is the owner of the schema appschema
and the database objects in that schema, that is, a
was used to create them. a
grants all necessary rights on the objects to b
, but none to c
.
b
owns a set of SECURITY DEFINER
functions that perform the data modifications on the tables in appschema
. b
revokes the EXECUTE
privilege on these functions from PUBLIC
and grants it to c
only.
It is very important that all these functions are defined with SET search_path = appschema
.
c
is the user that is used by the application. Except for the EXECUTE
privilege on b
's function, that user has no permissions beyond the right to connect to the database.
Now when c
executes any of the functions, they will run with b
s user context, that is, they can perform all operations that b
can.
Upvotes: 1