存取控管 Access Control防護之道

存取控管 Access Control防護之道

授權(存取控管)是針對特定資源發出存取請求,判斷該請求是否應該被核准或是拒絕. 要注意的是授權與認證是不同的. 這裡個名詞經常被混淆.

授權的設計可以由簡單開始,之後根據應用系統的需求演進為較為複雜的安全控管. 在設計階段的時候有些安全的設計需要考量. 一旦選定特定的授權控制機制後, 之後要再重新更改新的授權機制會比較困難.特別是在多租戶的使用環境下, 權限管理在應用系統安全防護更是重要.

強制所有的存取都需要經過權限控制

有許多的框架或是程式語言只有在程式碼中加入該功能的檢查時才會進行權限控制. 建議權限控制應該是中央控管,所有的存取都應該要再第一時間做權限驗證. 考慮可以設計一個自動過濾的機制, 將所有的存取都透過權限控制的方式檢查

預設不授權

透過自動權限檢查的機制, 考慮預設將所有沒有經過權限檢查的存取都不允許存取. 這樣可以避免新功能因為程式開發遺漏授權檢查而導致跳過授權驗證的步驟.

最小權限原則

當設計存取控制時, 所有的使用者或是系統元件應該都預設配置最小的權限,在最短的有效權限時間內執行相關的功能.

避免程式碼中寫死(Hard-Coded)權限控制

有許多情況權限控管被寫死在程式邏輯中. 這會讓安全的稽查變得特別困難且耗時. 如果可以的話, 權限控管的規則應該與程式分離. 另一個方式就是將權限檢查與最終權限決定分離.

程式碼

有許多的框架依據使用者角色來決定權限控制的權限. 透過是用者角色的權限控制也是通用的安全防護設計. 但是往往程式實作上卻是以使用者與對應的功能權限來做檢查. 這樣的檢查應該要定義使用者與功能對應權限對應關係. 舉例來說,使用者使用者通常會根據專案修改角色, 但是存取專案的相關權限商業功能也應該要加以定義

下面是不好的程式碼範例:

if (user.hasRole(“ADMIN”)) || (user.hasRole(“MANAGER”)) {

deleteAccount();

}

正確的程式範例:

if (user.hasAccess(“DELETE_ACCOUNT”)) {

deleteAccount();

}

伺服器端的信任資料要以權限控制為導向

有許多的資訊內容提供讓伺服器端作為權限控制的判斷(使用者的登入, 使用者權限, 使用者權限規則, 哪些功能與資料已被存取, 地理位置等),這些資訊由後端伺服器決定是否可以存取, 而非客戶端可以任意存取或是決定. 權限規則像是使用者角色或是權限控制規則不能成為用戶端任意存取的一部份. 一個標準的網站應用系統中, 用戶端資料只有id需要作為權限控制的輸入. 許多其他關於權限控制的資訊應該由後端伺服器決定是否能夠被存取.

 

Java範例

就像上述所討論, 建議將存取控制定義與商業邏輯分開. 這樣的安全設計方式就可以透過中央安全規則管理實現彈性化權限配置. 舉例來說 Apache Shiro API提供簡單的INI-based configuration file安全配置檔案讓權限控制規則可以透過模組的方式彈性調整. Apache Shiro 也可以與許多其它Java相容的框架運作 (Spring, Guice, JBoss, etc). Aspects也提供可以把權限控制與應用程式碼分離的機制,並且提供可以稽核的實作方式.

安全防護

參考

Leave a Reply

Your email address will not be published. Required fields are marked *