WEB應用安全設計思想
安全問題的本質問題是個很難探討的問題,許多人都無法給出相應的結論,那么讓我們來一步一步分析,通過安全設計過程得出結論。
信任關系的劃分是安全設計的基礎
安全問題的本質是信任問題。
提到這個,不得不說一個信任域的概念。當系統信任某些單元時,由這些單元組成的一片區域可以稱之為信任域。在數據流圖或者是拓跋圖上,都可以用一個邊界把這個域給界定出來。我說的這個概念,是一個廣義的概念,任何存在信任關系的系統中,都可以存在信任域。
比如一個機場,人們要登機,必須要先經過安檢,那么過了安檢后,在候機廳候機,就可以把候機廳看做是一個信任域。因為對于機場來說,候機廳內的區域是可信的。而候機廳外的區域是不可信的。
機場的安檢就是對跨越信任邊界的一個檢查。會檢查有沒有刀具,有沒有液體、打火機等。
那么安全問題是怎么發生的呢?首先是沒有合理的劃分信任域,或者是信任域比較混亂。
其次就是信任邊界的檢查出現問題的時候。這些問題可以是檢查不夠充分,或者是檢查沒有覆蓋到整個信任邊界。
而這些問題導致的結果,都是產生信任危機,也就產生安全問題了。
對于傳統的內存攻擊來說,一個字符串超出了分配給它的指定空間長度,也可以看做是對信任域的破壞,或者是缺乏審計。
所以信任域和信任邊界是非常重要的東西。在做安全方案的時候,首先就要依據資產等級,去劃分信任域和信任邊界。
我們要知道我們到底要保護什么東西,然后去分析有什么途徑能夠達到這些要保護的信任域。
在圈子里經常講的一個笑話就是,怎么做到安全?撥網線最安全。首先,這是一個謬論,因為網線拔掉后,可用性會受到影響。安全方案應該盡可能的避免犧牲可用性為代價,應該是為業務和應用服務的。拔網線是一種舍本逐末的做法。
其次,拔了網線真的就安全了嗎?
我們把物理隔絕的系統看做是一片信任域,那么它會信任什么?如何與外界做數據交互?
簡單的頭腦風暴一下,就可以知道,這樣的系統,可能會與外界發生數據交互的情況:
1. U盤有可能拷貝數據
2. 無線網卡有可能自動連接
3. 可能有人為的手工操作
那么以上這三條,都是有可能穿越我們的信任邊界,產生數據流動的行為。原本物理隔絕就是為了不信任外界的一切,產生數據流動后,就可能破壞信任關系。
再回過頭來看上面的機場的案例,把客流量看做是數據流量,它將穿越一道信任邊界,進入候機廳這個信任域,所以機場有安檢,來專門檢查這個穿越信任邊界的數據。安檢就是機場的安全方案。
-tips--------------------------------------------------------------------------
如果A信任B,或者A依賴于B,則B可以決定A的安全。常見的案例比如軟件中使用了第三方包,則第三方包可以決定A中相關數據的安全。
-------------------------------------------------------------------------------
某些視頻播放軟件使用了很多第三方的庫來解析很多不同的視頻格式,當第三方庫出現安全問題時,則直接導致這些視頻播放軟件也出現安全問題。
所以安全域的劃分是安全方案的基礎,劃分了安全域后,才能比較有針對性的設計安全方案。
訪問控制是安全設計的核心
訪問控制不僅僅包括權限。權限僅僅只是訪問控制的一部分。這里我們通常所說的權限都是垂直權限控制,它一般是基于角色的(role based)。
比如一個論壇里面,有匿名用戶,他們可能看不了帖子的內容。有普通用戶,他們能看帖子的內容。有管理員,他們能刪帖子,能置頂帖子。
那么匿名用戶、普通用戶、管理員就是三個不同的角色。
我們的大部分訪問控制系統,都是基于角色的。普通用戶沒辦法執行管理員的操作,因為訪問控制系統會校驗用戶的角色,以決定他們是否有足夠的權限去執行一次訪問。
訪問控制系統一般在整個系統中處于一個比較中心的位置,也只有讓他處在一個中心的、關鍵的位置,才能保證每次訪問都由它來控制。
但是目前我們的大多數系統都僅僅是垂直權限控制,而對水平權限控制方面卻做的不太好。
什么是水平權限控制?
這個概念是相對于垂直權限控制來說的。
A與B都是同一個角色的普通用戶。A上傳了一個頭像,系統給它編號為123,正常情況下,A可以執行http://www.test.com/delete?id=123”去刪除自己的頭像。
但是由于這個刪除操作僅僅校驗了用戶的角色,而沒有校驗提交該請求的用戶是否是A,從而導致B可以提交以上請求,去刪除A的頭像。
這就是一個典型的水平權限控制出錯的例子。
而很多系統中,同一個角色的用戶可以加入不同的用戶組,這些一個個的用戶組,就是一個水平權限控制的系統。
只是問題往往出在訪問控制系統的粒度上。如果劃分的粒度不夠細,那么一個用戶組內的用戶是否可以刪除或修改各自的數據?
對于粒度的劃分,我把一個訪問控制系統中的最小單位稱之為一個原子權限。無論是水平權限系統還是垂直權限系統,可能都是對原子權限的不同組合。
這個問題實際上是一個非常難以解決的問題,特別是在已經成型的大型系統中。對于現在的大型互聯網公司來說,網站的代碼一般都是幾十G的數量級,業務系統繁多。而水平權限控制的一般要求是,將所操作的數據與用戶聯系起來。
回到上面的例子:delete?id=123
那么怎么知道123這條數據,是A的呢?系統無從判斷,只能去查詢user表。如果業務系統一復雜,可能就涉及到跨表查詢或者是聯合查詢,甚至是跨庫查詢,這基本上是一場噩夢。
可是如果不進行二次查詢,則無法在根本的地方解決這個問題。可是二次查詢又會帶來性能上的消耗。真是一個很矛盾的事情。
所以最好的做法是在設計數據層的時候,事先考慮好這個問題,做好數據與用戶之間的關聯性。
如果已經成型的系統,就只能在外面包一層,把這個問題隱藏起來了。在本文的后面,會提到這種做法。
除了水平和垂直權限控制外,實際上一些規則,也可以看做是訪問控制。比如瀏覽器里的SOP(same original policy)。DOM、cookie等都有同源策略,也略有差別。但這些規則,都是屬于訪問控制系統,在整個安全體系中,處于核心的位置。
- -tips----------------------------------------------------
- 訪問控制系統一般會針對數據的RWX(讀、寫、執行)屬性進行授權,對發起請求方則進行水平或垂直的檢查。
- ---------------------------------------------------------
而在WEB中,極其理想的狀態,可以大膽的想象為,以session為單位建立原子權限,將數據與session關聯起來后,每個不同的session就是不同的信任域,對每個跨越信任邊界的請求進行水平、垂直的權限檢查,這樣就是一個極端理想的權限體系。這只是一個理想模型,在實踐中,需要根據實際情況進行分析。
WEB的安全設計過程比較繁瑣,本篇文章只向大家介紹了一部分,我們還會在后面的內容里繼續與大家分享的。
【編輯推薦】