In welcher Reihenfolge überprüft PostgreSQL die Objektberechtigungen?

16

Bei einer gegebenen Datenbankrolle user1wird eine Funktion something()als gespeicherte Prozedur definiert und eine Ansicht wie folgt erstellt:

CREATE VIEW view1 AS select * from something()

Und mit diesen Berechtigungen:

REVOKE ALL ON FUNCTION something FROM user1
REVOKE SELECT ON view1 FROM user1

Wenn ich renne SELECT * FROM view1, erhalte ich eine Fehlermeldung permission denied for function something().

Meine Frage ist, wenn ich die Auswahlberechtigungen für die Ansicht widerrufe, warum die Funktion aufgerufen wird? Ich hatte erwartet, etwas zu erhalten wie:

permission denied for relation view1

Vielen Dank!

Santios
quelle
2
AFAIK Es gibt keine definierte Reihenfolge, in der Berechtigungen überprüft werden.
Craig Ringer
@CraigRinger Danke! Ich denke, das ist dann das erwartete Verhalten. Da ich die Ansicht in einer API verfügbar mache, habe ich versucht, Implementierungsdetails der Ansicht nicht preiszugeben (da sich die Fehlermeldung über die Berechtigungen der Funktion beschwert, anstatt über die Ansicht).
Santios
1
Ich würde vermuten, dass Berechtigungen auf die gleiche Art und Weise ausgewertet werden wie Abfragepläne (z. B. von unten nach oben), und als solches wird das niedrigste Objekt zuerst ausgewertet, was in Ihrem Fall die something()Funktion ist. Ein schneller Test besteht darin, die Abfrage so zu ändern, dass Sie einen anderen EXPLAIN-Plan erhalten, und die Berechtigungen entsprechend anzupassen. Anschließend können Sie überprüfen, ob der Berechtigungsfehler für die something()Funktion ausgelöst wurde oder ob der neue Ausführungsplan neu bewertet wird.
John Eisbrener
Wenn Sie Berechtigungen für die Funktion erteilen und sie für die Ansicht widerrufen, sollte die zugrunde liegende Funktion nicht erwähnt werden
Amenadiel,

Antworten:

3

In diesem Fall geht es nicht um die Berechtigungsreihenfolge, sondern um die Ausführungsreihenfolge.

Zusammenfassend für PostgreSQL:

1- Ansichten, die auf Tabellen zugreifen, überschreiben die Tabellenberechtigung

2- Ansichten, auf die Funktionen zugreifen, müssen vor der Überprüfung alle Funktionen auswerten. Daher müssen die Funktionen vor dem Zugriff auf die Ansicht ausgeführt werden, auch wenn die Ansicht keine Auswahlberechtigungen hat.

Wie können wir das beweisen?

In postgresql können Ansichten Ihnen Berechtigungen zum Auswählen in einer Tabelle erteilen, auch wenn der Benutzer nicht über diese Berechtigungen verfügt.

Beispielsweise:

create view view2 as select * from table1;
revoke all on table1 from user1;
grant select on view2 to user1; 

Melden Sie sich als Benutzer 1 an:

select * from table1 (permission denied) 
select * from view2 (sucess - the query executes)

In diesem Fall kann der Benutzer view2 auswählen, auch wenn er keine Berechtigung zum Auswählen der Tabelle hat.

Was aber, wenn wir mit einer Funktion dasselbe tun ? Das Verhalten ist NICHT dasselbe. Lässt eine Funktion erstellen, die 5 Sekunden wartet, bevor 1 zurückgegeben wird (damit wir debuggen können, wenn postgresql die Funktion jedes Mal ausführt, wenn wir die Ansicht aufrufen)

CREATE OR REPLACE FUNCTION something() RETURNS integer
AS 'select 1 from pg_sleep(5);'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT; --this function will delay 5 seconds

create view view1 as select * from something();
revoke all on function something() from user1;
grant select on view1 to user1; 

Melden Sie sich als Benutzer 1 an:

select * from something(); (permission denied for something) 
select * from view1 (permission denied for something )

Die Berechtigung zum Ausführen der Auswahl in der Ansicht überschreibt nicht die Funktionsberechtigung. Selbst wenn wir die Berechtigungen von Ansicht1 widerrufen, wird in der Nachricht weiterhin angezeigt, dass postgresql unsere Abfrage aufgrund der Funktion gestoppt hat, unabhängig von der Berechtigung der Ansicht. (das ist genau das, was in der Frage passiert)

Aber wird die Funktion wirklich zuerst geprüft? Wenn wir der Funktion alle Berechtigungen erteilen, aber die Anzeigeberechtigung entziehen ...

grant all on function something to user1; 
revoke all on view1 from user1; 
select * from view1;
Delayed 5 seconds... (the function executed!) 
Permission denied for select on view1

Wie Sie sehen, WARTET postgresql 5 SEKUNDEN, bevor Sie sagen, dass wir keine Berechtigung zur Ausgabe der Ansicht haben , was zeigt, dass die Funktion "something ()" ausgeführt wird. Die Funktionsdatenrückgabe muss also vor der Prüfung der Sicht vorhanden sein.

Mit diesen Tests wissen wir nun, dass PostgreSQL zunächst alle Funktionen auswerten musste, bevor die Abfrage fortgesetzt werden konnte. Ebenso ist die Abfrage erst dann vorhanden, wenn alle Funktionen vollständig ausgeführt wurden. Daher kann die Ansicht für postgresql to nicht gelöst werden wissen, ob wir die Berechtigung zur Auswahl haben oder nicht.

Ich denke, dies beantwortet Ihre Frage in Bezug auf "Berechtigungsreihenfolge", aber warum muss postgresql alle Funktionen bewerten, bevor es fortfährt, das ist eine andere Frage ...

Anon
quelle