Postgres 12 RLS

Started by Laura Smithalmost 6 years ago5 messagesgeneral
Jump to latest
#1Laura Smith
n5d9xq3ti233xiyif2vp@protonmail.ch

Hi,

I'm having a little trouble with RLS in Postgres 12, although first time I've used RLS, so it might just be me !

The problem is that I am calling a function from a web-app, but the function seems to be executing as "postgres" even thouhg the web-app logs in as a completely different role ?

This means that current_user in the function resolves to "postgres" instead of the app user.

This is an example of a function :
create function addses(p_regid text,p_msgid text,p_reqid text) returns integer AS $$
BEGIN
UPDATE foo_regs set reg_aws_ses_msgid=p_msgid,reg_aws_amzn_requestid=p_reqid where uuid=p_regid;
IF FOUND THEN
return 1;
ELSE
return 0;
END IF;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
grant execute on function addses(p_regid text,p_msgid text,p_reqid text) to myappuser;

The foo_regs table has the following RLS policy:
Policies:
POLICY "foo_regs_policy"
USING (((event_id = CURRENT_USER) AND (reg_hide IS FALSE)))

#2Paul Förster
paul.foerster@gmail.com
In reply to: Laura Smith (#1)
Re: Postgres 12 RLS

Hi Laura,

On 08. Jun, 2020, at 12:17, Laura Smith <n5d9xq3ti233xiyif2vp@protonmail.ch> $$ LANGUAGE plpgsql SECURITY DEFINER;

you might want to use security invoker instead of definer.

https://www.postgresql.org/docs/current/sql-createfunction.html#SQL-CREATEFUNCTION-SECURITY

https://www.cybertec-postgresql.com/en/abusing-security-definer-functions/

Cheers,
Paul

#3Laura Smith
n5d9xq3ti233xiyif2vp@protonmail.ch
In reply to: Paul Förster (#2)
Re: Postgres 12 RLS

On Monday, 8 June 2020 11:25, Paul Förster <paul.foerster@gmail.com> wrote:

Hi Laura,

On 08. Jun, 2020, at 12:17, Laura Smith n5d9xq3ti233xiyif2vp@protonmail.ch $$ LANGUAGE plpgsql SECURITY DEFINER;

you might want to use security invoker instead of definer.

https://www.postgresql.org/docs/current/sql-createfunction.html#SQL-CREATEFUNCTION-SECURITY

https://www.cybertec-postgresql.com/en/abusing-security-definer-functions/

Cheers,
Paul

Hi Paul,

I had a lightbulb moment just now and tried that, but it doesn't seem to be working.

The app returns "pg_execute(): Query failed: ERROR: permission denied for table...."

This is despite me:
• Changing to SECURITY INVOKER on the PG function.
• Granting the app user relevant perms on the underlying table
• Re-granting execute for the app on the function

Am I missing somehthing ?

#4Paul Förster
paul.foerster@gmail.com
In reply to: Laura Smith (#3)
Re: Postgres 12 RLS

Hi Laura,

On 08. Jun, 2020, at 12:46, Laura Smith <n5d9xq3ti233xiyif2vp@protonmail.ch> I had a lightbulb moment just now and tried that, but it doesn't seem to be working.

The app returns "pg_execute(): Query failed: ERROR: permission denied for table...."

This is despite me:
• Changing to SECURITY INVOKER on the PG function.
• Granting the app user relevant perms on the underlying table
• Re-granting execute for the app on the function

Am I missing somehthing ?

another possibility maybe is to use session_user instead of current_user in your policy.

current_user name user name of current execution context
session_user name session user name

The latter is the name of the user who actually started the session. So it should be myappuser in your case.

https://www.postgresql.org/docs/current/functions-info.html

Cheers,
Paul

#5Laura Smith
n5d9xq3ti233xiyif2vp@protonmail.ch
In reply to: Paul Förster (#4)
Re: Postgres 12 RLS

On Monday, 8 June 2020 12:42, Paul Förster <paul.foerster@gmail.com> wrote:

Hi Laura,

On 08. Jun, 2020, at 12:46, Laura Smith n5d9xq3ti233xiyif2vp@protonmail.ch I had a lightbulb moment just now and tried that, but it doesn't seem to be working.
The app returns "pg_execute(): Query failed: ERROR: permission denied for table...."
This is despite me:
• Changing to SECURITY INVOKER on the PG function.
• Granting the app user relevant perms on the underlying table
• Re-granting execute for the app on the function
Am I missing somehthing ?

another possibility maybe is to use session_user instead of current_user in your policy.

current_user name user name of current execution context
session_user name session user name

The latter is the name of the user who actually started the session. So it should be myappuser in your case.

https://www.postgresql.org/docs/current/functions-info.html

Cheers,
Paul

Thanks Paul, will experiment with session_user.

But actually I found the solution, the function I was testing was using "INSERT ON CONFLICT UPDATE". And it seems that requires SELECT permissions due to "ON CONFLICT" (appuser was previously only granted INSERT and UPDATE).