Neue PL/SQL Features VI - Grants an Prozeduren
Im vorigen Blog-Eintrag in der Serie der neuen PL/SQL-Features haben wir das Feature "Inherit Privileges" vorgestellt, mit dem sich Privilege Escalation Attacken besser vermeiden lassen. Auch der vorerst letzte Beitrag in der Serie befasst sich mit einem ähnlichen Thema. Es geht wieder um Prozeduren mit Invokers Rights, also solchen, die mit den Rechten des Aufrufenden ausgeführt werden. Allerdings geht es diesmal in die umgekehrte Richtung, es werden nicht die eventuell höheren Rechte des Ausführenden ausgenutzt sondern es geht um die Rechte, um die erfolgreich Prozedur ausführen zu können.
Nehmen wir an, innerhalb einer Prozedur werden Objekte verwendet, auf die der Ausführende gar keine Berechtigung hat. Als Beispiel soll eine Prozedur dienen, die über V$SESSION und V$PROCESS die Prozess-ID der angemeldeten Session ermittelt. Das würde zwar mit Definer Rights gut funktionieren, für unser Beispiel legen wir diese Funktion aber als Invoker Rights an. Der Endnutzer erhält dann die EXECUTE-Berechtigung auf diese Funktion.
SQL> show user
USER is "SYS"
SQL> create or replace function fnc_get_os_pid
2 return number
3 authid current_user
4 as
5 v_spid v$process.spid%TYPE;
6 begin
7 select spid
8 into v_spid
9 from sys.v_$session s, sys.v_$process p
10 where s.paddr = p.addr
11 and s.sid = sys_context('USERENV', 'SID');
12 return v_spid;
13 end;
14 /
Function created.
SQL> select fnc_get_os_pid from dual;
FNC_GET_OS_PID
--------------
75700
SQL> grant execute on fnc_get_os_pid to schema_owner;
Grant succeeded.
SQL> conn schema_owner/owner@odax5-base-00:1521/mmi1.support.robotron.de
Connected.
SQL> select sys.fnc_get_os_pid from dual;
select sys.fnc_get_os_pid from dual
*
ERROR at line 1:
ORA-00942: table or view does not exist
ORA-06512: at "SYS.FNC_GET_OS_PID", line 7
Folgerichtig kann die Funktion nicht ausgeführt werden, da dem Nutzer die Rechte auf die Systemviews fehlen. Normalerweise würde man nun das SELECT-Recht auf diese Views direkt an den Nutzer vergeben, aber damit erlangt er Zugang zu mehr Information als es vielleicht gewünscht ist. Daher gibt es nun die Möglichkeit, SELECT-Rechte an eine Prozedur zu vergeben. Dazu wird eine Rolle angelegt, dieser werden die SELECT-Rechte zugewiesen und die Rolle wiederum wird an die Prozedur gegrantet.
SQL> conn / as sysdba
Connected.
SQL> create role r_get_os_pid;
Role created.
SQL> grant select on v_$session to r_get_os_pid;
Grant succeeded.
SQL> grant select on v_$process to r_get_os_pid;
Grant succeeded.
SQL> grant r_get_os_pid to function fnc_get_os_pid;
Grant succeeded.
SQL> conn schema_owner/owner@odax5-base-00:1521/mmi1.support.robotron.de
Connected.
SQL> select sys.fnc_get_os_pid from dual;
FNC_GET_OS_PID
--------------
78737
Wie man sieht, kann der Nutzer nun die Funktion erfolgreich ausführen und erhält ein Ergebnis. Auf die zugrundiegenden Systemviews hat der Nutzer aber nach wie vor keinen Zugriff.
SQL> select * from sys.v_$session;
select * from sys.v_$session
*
ERROR at line 1:
ORA-00942: table or view does not exist
Nun ist dieses Beispiel mit SYS als Besitzer der Funktion vielleicht nicht gerade praxistauglich. Im Normalfall wird ein Besitzer solch einer Funktion einfach die Rolle mit der Admin-Option zugewiesen bekommen. Er kann dann die nötigen Rechte selbst an die Rolle vergeben und die Rolle darf er dann dank der Admin-Option an seine Funktionen vergeben. Hier noch mal ein Beispiel dazu:
SQL> show user
USER is "SYS"
SQL> create role r_functions;
Role created.
SQL> grant r_functions to schema_owner with admin option;
Grant succeeded.
SQL> conn schema_owner/owner@odax5-base-00:1521/mmi3.support.robotron.de
Connected.
SQL> create table app_users(username varchar2(30), status varchar2(10));
Table created.
SQL> insert into app_users values ('SCHEMA_OWNER', 'OPEN');
1 row created.
SQL> insert into app_users values ('SCHEMA_USER', 'OPEN');
1 row created.
SQL> commit;
Commit complete.
SQL> create or replace function fnc_get_my_user_status return varchar2
2 authid current_user
3 as
4 v_status app_users.status%TYPE;
5 begin
6 select status into v_status from schema_owner.app_users where username = user;
7 return v_status;
8 end;
9 /
Function created.
SQL> grant select on app_users to r_functions;
Grant succeeded.
SQL> grant r_functions to function fnc_get_my_user_status;
Grant succeeded.
SQL> grant execute on fnc_get_my_user_status to schema_user;
Grant succeeded.
SQL> conn schema_owner/owner@odax5-base-00:1521/mmi3.support.robotron.de
Connected.
SQL> select schema_owner.fnc_get_my_user_status from dual;
FNC_GET_MY_USER_STATUS
--------------------------------------------------------------------------------
OPEN
Wir hoffen, das Prinzip damit verdeutlicht zu haben. Bei Fragen stehen wir Ihnen wie immer gerne zur Verfügung.
Kommentare
Keine Kommentare