Re: [PATCH] Add reloption for views to enable RLS

From: walther(at)technowledgy(dot)de
To: Laurenz Albe <laurenz(dot)albe(at)cybertec(dot)at>, Christoph Heiss <christoph(dot)heiss(at)cybertec(dot)at>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: [PATCH] Add reloption for views to enable RLS
Date: 2022-02-04 21:28:51
Message-ID: 87c4c559-4ade-d089-2317-de9077e698b2@technowledgy.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Christoph Heiss wrote:
> As part of a customer project we are looking to implement an reloption for views which when set, runs the subquery as invoked by the user rather than the view owner, as is currently the case.
> The rewrite rule's table references are then checked as if the user were referencing the table(s) directly.
>
> This feature is similar to so-called 'SECURITY INVOKER' views in other DBMS.

This is a feature I have long been looking for. I tested the patch (v5)
and found two cases that I feel need to be either fixed or documented
explicitly.

Case 1 - Schema privileges:

create schema a;
create table a.t();

create schema b;
create view b.v with (security_invoker=true) as table a.t;

create role alice;
grant usage on schema b to alice; -- missing schema a
grant select on table a.t, b.v to alice;

set role alice;
table a.t; -- ERROR: permission denied for schema a (good)
table b.v; -- no error (good or bad?)

User alice does not have USAGE privileges on schema a, but only on table
a.t. A SELECT directly on the table fails as expected, but a SELECT on
the view succeeds. I assume the schema access is checked when the query
is parsed - and at that stage, the user is still the view owner?
The docs mention explicitly that *all* objects are accessed with invoker
privileges, which is not the case.

Personally I actually like this. It allows to keep a view-based api in a
separate schema, while:
- preserving full RLS capabilities and
- forcing the user to go through the api, because a direct access to the
data schema is not possible.

However, since this behavior was likely unintended until now, it raises
the question whether there are any other privilege checks that are not
taking the invoking user into account properly?

Case 2 - Chained views:

create schema a;
create table a.t();

create role bob;
grant create on database postgres to bob;
grant usage on schema a to bob;
set role bob;
create schema b;
create view b.v1 with (security_invoker=true) as table a.t;
create view b.v2 with (security_invoker=false) as table b.v1;

reset role;
create role alice;
grant usage on schema a, b to alice;
grant select on table a.t to bob;
grant select on table b.v2 to alice;

set role alice;
table b.v2; -- ERROR: permission denied for table t (bad)

When alice runs the SELECT on b.v2, the query on b.v1 is made with bob
privileges as the view owner of b.v2. This is verified, because alice
does not have privileges to access b.v1, but no such error is thrown.

b.v1 will then access a.t - and my first assumption was, that in this
case a.t should be accessed by bob, still as the view owner of b.v2.
Clearly, this is not the case as the permission denied error shows.

This is not actually a problem with this patch, I think, but just
highlighting a quirk in the current implementation of views
(security_invoker=false) in general: While the query will be run with
the view owner, the CURRENT_USER is still the invoker, even "after" the
view. In other words, the current implementation is *not* the same as
"security definer". It's somewhere between "security definer" and
"security invoker" - a strange mix really.

Afaik this mix is not documented explicitly so far. But the
security_invoker reloption exposes it in a much less expected way, so I
only see two options really:
a) make the current implementation of security_invoker=false a true
"security definer", i.e. change the CURRENT_USER "after" the view for good.
b) document the "security infiner/devoker" default behavior as a feature.

I really like a), as this would make a clear cut between security
definer and security invoker views - but this would be a big breaking
change, which I don't think is acceptable.

Best,

Wolfgang

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2022-02-04 21:29:19 Re: Release notes for February minor releases
Previous Message Michael Banck 2022-02-04 21:27:54 Re: Release notes for February minor releases