現今大多數Web 應用程式都需要至少採用某種基本的安全策略。例如,提供用口令保護的內容的網站、僅具有管理員後端的網站、網誌和個人雜誌、電子商務網站、企業內部網路,等等。
建構這些類型的Web 應用程式最常用的設計方法是將安全性原則整合到Web 應用程式的業務邏輯中,也就是由應用程式決定某個使用者是否有權存取資料庫中的某個資料。在這種情況下,資料庫的角色僅為儲存資料和依請求提供資料。換句話說,如果Web 應用程式命令資料庫提供特定信息,則資料庫會直接執行該命令而不檢查使用者的權限。
在該文中,您將學習如何利用Oracle 內建的安全特性在資料庫層級執行應用程式安全規則,以提高應用程式的整體安全性。作為附帶的好處,直接在資料庫中實現資料存取安全性不但有助於提高應用程式的安全性,而且有助於降低複雜性。
對資料庫端安全性的需求
從Web 應用程式控制資料存取會怎麼樣?大多數情況下沒有問題;這是個不錯的解決方案,尤其是在涉及的資料是非任務關鍵或絕密的時候。許多書和線上資源中都用到了該方法。實際上,有本很受歡迎的PHP/MySQL 書明確反對每個應用程式創建一個以上的資料庫使用者帳戶,這是因為「額外的使用者或複雜的權限會因為某個操作在繼續前要檢查更多的資訊而降低MySQL 的執行速度」。確實如此;但是,在放棄將安全性整合到資料庫邏輯中的想法之前可能要考慮幾件事情。我們來看以下範例。
假設建立一個內容管理系統(CMS)。其中使用資料庫來儲存網站上發布的內容。大部分資料是公開的,允許匿名Web 使用者讀取;但只允許編輯更改資料。使用單一資料庫帳戶存取和修改資料庫中的記錄,並透過用口令保護僅管理員可以存取的頁面的存取權限以PHP 程式碼控制安全性。
如果Web 應用程式的公共端遭受了一個諸如公共搜尋表單(即編碼不夠嚴密的表單)上的SQL 注入的攻擊,則該入侵者可能能夠對該公用帳戶可以存取的資料庫物件執行任意SQL 語句。當然,就這裡的情形而言,執行SELECT 語句不會造成什麼大問題,這是因為資料本來就是公共的。但由於公共權限和管理權限使用相同資料庫帳戶,入侵者也能執行UPDATE 和DELETE 語句,甚至是從資料庫中刪除表。
怎麼才能防止該情況的發生呢?最簡單的方法就是徹底限制公共資料庫帳戶修改資料的權限。讓我們來看看Oracle 是如何解決這個問題的。
Oracle 安全性基本概述
Oracle 資料庫為Web 開發人員提供了控制資料存取的許多方法,從管理對特定資料庫物件(如表、視圖和流程)的存取到控制個別行或列的資料的存取。很顯然,對Oracle 每個安全特性或可用選項的討論超出了本文的範圍。在這裡,我們將不涉及過多細節,而僅介紹Oracle 資料存取安全性的最基本方面:
·驗證和使用者帳戶·權限·角色
驗證和使用者帳戶。 與其他資料庫一樣,要求存取Oracle 的每個使用者(資料庫帳戶)必須通過驗證。驗證工作可以由資料庫、作業系統或網路服務來做。除基本的驗證(口令驗證)外,Oracle 還支援強驗證機制,如Kerberos、CyberSafe、RADIUS,等等。
角色。 Oracle 角色是一個權限的有名集。儘管可以直接授予使用者帳戶權限,但使用角色可以極大簡化使用者管理,尤其是需要管理大量使用者時。建立易管理的小角色,然後根據使用者的安全等級授予使用者一個或多個角色,這樣做的效率非常高。更不用說修改權限變得如何簡單了— 只需修改角色關聯的角色即可,無需修改每個使用者帳戶。
為了簡化新使用者創建初期的工作,Oracle 自帶了三個預先定義的角色:
·CONNECT 角色— 此角色使用戶可以連接資料庫以及執行基本的操作,例如建立自己的表。預設情況下,該角色不能存取其他使用者的表。
·RESOURCE 角色— RESOURCE 角色與CONNECT 角色相似,但它允許使用者擁有較多的系統權限,例如建立觸發器或預存程序。
·DBA 角色— 允許使用者擁有所有系統權限。
使用中的授權和權限
在本部分中,我們將討論如何使用Oracle 的授權和權限來提高本文開頭部分討論的那個簡單CMS 範例的安全性。假定,提供給應用程式使用者的內容儲存在WEB_CONTENT 表中。
首先,建立該表。啟動Oracle 資料庫特別版,以系統管理員身分登入。如果還沒有釋放範例HR 用戶,請將其釋放。請按照特別版安裝隨附的入門指南中的指示操作。請注意,預設情況下,HR 使用者被賦予RESOURCE 角色。在這裡,賦予該用戶DBA 角色,這樣就可以使用該帳戶管理CMS 應用程式的資料庫方面了。當然,不會使用HR 使用者帳戶進行線上訪問,只用它管理資料庫。
現在,可以使用物件瀏覽器或透過執行SQL Commands 視窗建立新表。以下是建立該表的程式碼:
CREATE TABLE WEB_CONTENT (
page_id NUMBER PRIMARY KEY,
page_content VARCHAR2(255)
);
由於該表是使用HR 使用者帳戶建立的,因此該表歸HR 帳戶所有並位於HR 模式中,並且在明確授予其他使用者存取該表的權限前,其他使用者無法存取該表。如果不信,可以建立一個新用戶,用該用戶存取WEB_CONTENT 表試試。
現在,建立兩個新用戶,CMS_USER 和CMS_EDITOR。最終,將授予CMS_USER 對WEB_CONTENT 表的唯讀權限,並將該使用者用來作為匿名Web 使用者提供內容的資料庫帳戶。 CMS_EDITOR 帳戶將在該表上擁有更多權限,並將用作CMS 編輯的帳戶(該帳戶需要更改和維護該表中的資料)。
可以使用XE 的圖形介面或透過執行以下命令建立新使用者:
CREATE USER cms_user IDENTIFIED BY cms_user;
CREATE USER cms_editor IDENTIFIED BY cms_editor;
(出於簡化的目的,此處的口令與使用者名稱對應。)
為了讓這兩個帳戶都登入資料庫,我們需要賦予它們CONNECT 角色。為此,在XE 圖形介面的Administration/Database Users 部分選取使用者資訊下的CONNECT 複選框,或執行以下命令:
GRANT CONNECT to cms_user;
GRANT CONNECT to cms_editor;
現在,如果嘗試以CMS_USER 或CMS_EDITOR 使用者登入並試圖從WEB_CONTENT 表讀取資料(select * from hr.web_content;),將遇到以下錯誤:
ORA-00942:table or view does not exist
為了存取資料或僅是看到表,需要授予CMS_USER 和CMS_EDITOR 帳戶對WEB_CONTENT 表的唯讀權限:
GRANT SELECT on hr.web_content to cms_user;
GRANT SELECT on hr.web_content to cms_editor;
以上程式碼讓這兩個帳號可以對WEB_CONTENT 資料表執行SELECT 語句。如果嘗試執行其他語句,則會遇到錯誤。例如,插入一行:
INSERT INTO hr.web_content (page_id,page_content) VALUES (1,'hello world');
將產生錯誤訊息
ORA-01031:insufficient privileges
要允許CMS_EDITOR 更改該表的內容,需要授予以下權限:
GRANT INSERT,UPDATE,DELETE on hr.web_content to cms_editor;
從現在起,CMS_EDITOR 帳號可以對WEB_CONTENT 表執行INSERT、UPDATE 和DELETE 語句。
您看,這有多簡單!可見透過角色管理權限是更有效的方法。如果使用的Oracle 資料庫不是XE,可以執行以下操作:
建立角色:
CREATE ROLE reader;
CREATE ROLE writer;
授予角色權限:
GRANT SELECT ON web_content TO reader;
GRANT INSERT,UPDATE,DELETE ON web_content TO writer;
賦予使用者角色:
GRANT reader TO cms_user;
GRANT reader TO cms_editor; (they need to read too)
GRANT writer TO cms_editor;
請注意,如果變更READER 角色的定義,則這些變更會影響所有具有該角色的使用者帳戶。如果是直接將權限授予使用者的,則必須逐一更新每個使用者帳戶。
完成上述步驟後,可以配置PHP 應用程序,使之對由匿名Web 用戶請求的所有資料庫連接均使用CMS_USER 帳戶,對由受口令保護的管理頁面引發的連接使用CMS_EDITOR 帳戶。現在,即使公共網頁 表單受到攻擊,該攻擊對資料庫的影響將微乎其微,這是因為CMS_USER 帳戶僅具有唯讀權限。
結論
在本文中,我們只是簡單介紹了Oracle 資料存取安全性的一些最基本的特性。此外,Oracle 還有許多其他特性,可將您的Web 應用程式的安全性提高到一個新的等級— 包括虛擬專用資料庫(VPD) 和標籤安全性。