確保Oracle資料庫安全的技術原則之一,就是仔細分析有關使用者組PUBLIC的使用方式。使用者組PUBLIC,顧名思義,表示資料庫中的每一位使用者,因此,對PUBLIC使用者組授予許可權其實也就是對資料庫中的每一位使用者都授予了相應的許可權。這是在授予或撤銷許可權時非常有用的一條捷徑。但也可能帶來巨大的安全隱患,尤其是在試圖確保以最少許可權的方式運行資料庫時,更是如此。
2.5.1 何時給PUBLIC組授予許可權
在很多時候,給PUBLIC授予許可權是比較切合實際的,並且不會產生安全隱患。例如,絕大部分的Oracle資料庫應用開發人員都知道DUAL表非常有用,而且絕對不含有敏感資訊。對於很多其他過程和函數來說,情況也是如此—— SYSDATE函數就是一個很好的例子,它很有用也不會產生安全隱患。因此,PUBLIC組訪問DUAL表和SYSDATE函數不會帶來安全風險。
遺憾的是,很難知道給PUBLIC授予許可權是不是真的會帶來安全風險。當在開發應用時,需要謹慎地決定給PUBLIC授予什麼樣的許可權—— 如果需要授予許可權的話。
同時也需要瞭解有些在目前不會帶來風險,卻有可能會在將來帶來風險的問題。例如,假設在一個Web應用中,有一張表格儲存體使用者的選擇項。初始時,允許使用者在表中儲存他們在製作個人首頁時所使用的背景顏色、前景顏色以及字型類型。這些資訊都不屬于敏感資訊,因此,可以被任何使用者查看。
scott@KNOX10g> CREATE TABLE user_prefs
2 (background_color VARCHAR2(6),
3 foreground_color VARCHAR2(6),
4 font_style VARCHAR2(20));
Table created.
scott@KNOX10g> GRANT SELECT ON user_prefs TO PUBLIC;
Grant succeeded.
後來,可能需要在該表中添加一項敏感的屬性,例如,允許使用者在表中儲存所喜歡的首頁和應用的超連結。
scott@KNOX10g> ALTER TABLE user_prefs ADD favorite_links VARCHAR2(250);
Table altered.
在添加屬性之後,將會完全改變表的敏感性。而授予PUBLIC組的許可權也應該被撤銷。管理PUBLIC組許可權的安全準則為:只要不確定是否安全,就不要給PUBLIC授予許可權。
2.5.2 Oracle 支援的對象
為了有效地確保Oracle資料庫的安全,需要考慮開發的或購買的應用以及Oracle資料庫物件已經給PUBLIC授與權限。
需要仔細考慮由兩個Oracle對象預設授予PUBLIC的許可權問題:
● 對資料字典視圖的訪問 有些資料字典的視圖會泄露使用者的資訊,從而可以被利用發起針對資料庫的攻擊。
● 對過程的執行 這包括PL/SQL函數、程式、包以及Java程式。這些過程能執行很多有用的函數—— 例如開啟網路連接、從啟動並執行系統中讀取檔案、設定有關使用者或應用的認證資訊—— 所有以上過程都可以被用在稍後將要介紹的資料庫安全處理過程中,例如存取控制和審計。
1. PUBLIC組對字典視圖的訪問
通過限制對敏感性資料的訪問,Oracle資料庫提供了對資料庫字典中繼資料的安全保護措施。隨著時間的推移,對“敏感性資料”的定義已經有了若干發展:初始時,敏感性資料指的是加密的使用者密碼之類的表項;現在,甚至是資料庫的使用者名稱也被看作是敏感性資料。然而,PUBLIC組仍然可以訪問其中的部分資料。
例如,ALL_USERS視圖可以被PUBLIC組訪問,而且其中列出了每一個資料庫模式的使用者名稱。駭客們經常使用的一招就是擷取並利用合法的使用者帳號試圖訪問其他的帳號。資料庫許可權選擇模式(MDYS)、預設的應用帳號以及使用者的帳號都會被ALL_USERS視圖列出,而這正成為了惡意使用者最有效目標。合法的資料庫使用者成為了針對資料庫的有效攻擊目標!而且,惡意使用者很容易就會說:“噢!看啊!資料庫中安裝了<insert option name or your application here>選項。讓我使用預設的密碼試著訪問這個被授權的帳號看看!”
因此,應該考慮撤銷PUBLIC組對某些資料庫中繼資料訪問的許可權。而利用ALL作為SYS對象名稱的首碼則是不錯的主意:
SELECT table_name
FROM dba_tab_privs
WHERE grantee = 'PUBLIC'
AND owner = 'SYS'
AND PRIVILEGE = 'SELECT'
AND table_name LIKE 'ALL%';
2. 受損的對象
在撤銷PUBLIC組對預設資料庫對象存取權限的時候,還應該瞭解在撤銷的同時可能會損害哪些當前已存在的程式或應用。下面的例子顯示了當撤銷PUBLIC對ALL_USERS視圖的存取權限後,有20個資料庫物件變得無效:
sys@KNOX10g> SELECT count(*) FROM all_objects
2 WHERE status = 'INVALID';
COUNT(*)
----------
0
1 row selected.
sys@KNOX10g> REVOKE SELECT ON all_users FROM PUBLIC;
Revoke succeeded.
sys@KNOX10g> SELECT count(*) FROM all_objects
2 WHERE status = 'INVALID';
COUNT(*)
----------
20
1 row selected.
損害並不是不可修複的。如果某個應用依賴於曾經授予PUBLIC組的某個許可權,那麼可以直接給這個應用授予相應的許可權從而進行修複工作。對於資料字典視圖,下面列出了需要直接授予許可權的模式:
sys@KNOX10g> -- Show whose objects are broken.
sys@KNOX10g> SELECT distinct owner
2 FROM all_objects
3 WHERE status = 'INVALID';
OWNER
--------------------
DMSYS
EXFSYS
LBACSYS
SYS
SYSMAN
XDB
6 rows selected.
在上述模式中,部分模式擁有系統許可權SELECT ANY DICTIONARY,通過該許可權可以訪問ALL_USERS視圖。這些模式中的部分對象將會在沒有授予任何許可權的情況下重新編譯;而其他一些模式則需要直接被授予有關ALL_USERS視圖的許可權。通過使用如下代碼中黑體部分的SQL函數可以列出仍然需要被直接授予相關許可權的模式。這段代碼的運行結果將列出需要被直接授予相關許可權的模式:
sys@KNOX10g> -- create list of users who require
sys@KNOX10g> -- direct select privileges on ALL_USERS
sys@KNOX10g> SELECT DISTINCT 'grant select on all_users to '
2 || owner
3 || ';' sql_command
4 FROM (SELECT DISTINCT owner
5 FROM all_objects
6 WHERE status =
7 'INVALID'
8 AND owner != 'SYS'
9 MINUS
10 SELECT grantee
11 FROM dba_sys_privs
12 WHERE PRIVILEGE =
13 'SELECT ANY DICTIONARY');
SQL_COMMAND
------------------------------------------------------------
grant select on all_users to DMSYS;
grant select on all_users to EXFSYS;
grant select on all_users to LBACSYS;
grant select on all_users to XDB;
4 rows selected.
在SQL_COMMAND的值中利用複製和粘貼方法,可以給需要授權的使用者直接授予相應的許可權。當授權後,這些模式中的無效對象需要被重新編譯。
遺憾的是,幾乎不可能對撤銷許可權的後果進行預測,這也就是Oracle為什麼還沒有撤銷PUBLIC的有關資料庫中繼資料視圖的許可權。而在Oracle Database Security Guide中也警告說撤銷PUBLIC的DML許可權並不是一件很簡單的事:
撤銷PUBLIC的許可權可能會引起一連串的影響。如果從PUBLIC中撤銷任何有關DML操作的許可權,那麼資料庫中的所有過程,包括函數和包,在被使用之前都必須重新認證。因此在給PUBLIC授予或撤銷與DML相關的許可權時需要格外小心。
3. 程式中的PUBLIC許可權
下面剖析器中授予PUBLIC的執行許可權。再次說明:不能在此列出更多的程式,而且這些程式經常會有變化。而在確保之前所介紹的視圖中的程式的安全時也面臨同樣的問題。但是,知道有哪些程式能完成哪些功能對於理解其安全風險是非常重要的—— 如果存在安全風險的話。
最值得關注的是那些以DBMS%和UTL%開始的程式:
SELECT table_name
FROM dba_tab_privs
WHERE grantee = 'PUBLIC'
AND owner = 'SYS'
AND PRIVILEGE = 'EXECUTE'
AND table_name LIKE 'DBMS%'
OR table_name LIKE 'UTL%'
ORDER BY 1;
警告:
對於這些程式或SYS的對象,不要吝嗇您的評估。資料庫中的所有對象和應用都應該被評估。
在Oracle Database Security Guide中建議撤銷PUBLIC的有關UTL_SMTP、UTL_TCP、UTL_HTTP以及UTL_FILE的執行許可權。而我們不僅僅只是撤銷上述這些執行許可權,還應該記住這些執行許可權限制了對應用、使用者以及對象的訪問。
正如上述的中繼資料樣本,經常有應用依賴於授予這些程式的PUBLIC許可權。而為了成功地刪除這些許可權,不僅需要理解其依賴關係,還需要解決在撤銷許可權過程中所出現的任何問題。第6章提供了關於撤銷DBMS_SESSION包的執行許可權的樣本。