垂直權限漏洞與水平權限漏洞

一、水平權限漏洞

簡單舉例:假設A可以更改1 2 3三條數據 而B可以更改 2 3條數據。

那麼我們一般會怎麼做呢,會讓用戶A查詢到123條數據,而用戶B查詢到23條數據

但是一般情況下,我們是對接口做的做的權限驗證 此時B權限會拿到23條數據,那麼B提交修改的時候只需要將修改的id更改成1的id即可(很多情況下我們會使用主鍵自增長的方式),所以很容易出現問題。

修復方案0:

先看一個有問題的方案:將addressid改成一個具有一定長度的隨機字符串,如5d41402abc4b2a76b9719d911017c592,認爲只有有權限的人才能得到這個入口,而且不能通過加1、減1的方式預測別人的入口,因此不再做進一步的權限檢查(很多初級的招聘頁面都是以這種方式來管理簡歷的)。這個方案看上去沒有問題,可是和國內的環境結合起來就會悲劇——至少我遇到過的,搜狗瀏覽器會把用戶發送的請求上傳到服務器上,作爲其搜索引擎爬蟲的爬取源,這樣爬蟲就會通告查詢操作得到相關的對象信息,並展示在搜索引擎上,如果對象信息包含敏感內容,則產生隱私泄露的安全事件。

 

修復方案1:

這個是最直接有效的修復方案:在web層的邏輯中做鑑權,檢查提交CRUD請求的操作者(通過session信息得到)與目標對象的權限所有者(查數據庫)是否一致,如果不一致則阻斷。這個方案實現成本低、能確保漏洞的修復質量,缺點是增加了一次查庫操作。我之前一直用這種方案來對已發生的水平權限漏洞做緊急修復。

 

修復方案2:

我認爲最正規的方案:把權限的控制轉移到數據接口層中,避免出現select/update/delete ... where addressID=#addressID#的SQL語句,使用selectt/update/delete... where addressID=#addressID# and ownerId=#userId#來代替,要求web層在調用數據接口層的接口時額外提供userid,而這個userid在web層看來只能通過seesion來取到。這樣在面對水平權限攻擊時,web層的開發者不用額外花精力去注意鑑權的事情,也不需要增加一個SQL來專門判斷權限——如果權限不對的話,那個and條件就滿足不了,SQL自然就找不到相關對象去操作。而且這個方案對於一個接口多個地方使用的情況也比較有利,不需要每個地方都鑑權了。但這個方案的缺陷在於實現起來要改動底層的設計,所以不適合作爲修復方案,更適合作爲統一的控制方案在最開始設計時就注意這方面的問題。

 

修復方案3:

今天開發同學提到一種我之前沒想到過的方式,實際上是對方案1的修改:在生成表單時,增加一個token參數,而token=md5(addressId+sessionId+key);在處理請求時,用addressId、sessionId和key來驗證token。這樣的方案實現起來很簡單,又不增加額外的SQL查詢開銷,看起來比方案1更好。可我之前沒有想到過這種方案,乍一看又是把鑑權和操作這一串同步的操作異步化了(實際上是在生成表單的時候鑑權並生成token,然後在操作時只驗證token而不鑑權),所以一時還拿不準這樣會不會有啥問題~不過我是想了半天也找不到漏洞哈~

 

修復方案4:

把這種屬主、權限、對象、操作的場景抽象成一個統一的框架,在框架內一個地方實現權限的管理和檢查。當然這個說起來有點扯淡了,在產品設計階段是不是有人願意花大成本來設計相關框架呢?如果最開始沒有框架,那麼什麼時候願意花更大的成本去遷移呢?我想最終還是會按方案1、2、3來吧。

總結:方案0是不可行方案。

          方案一:說是在web層邏輯中做鑑權限,只能把1數據從數據庫中取出,並判斷該用戶時候有查詢該數據的權限,所以說是可以的。

         方案二:是可行的在service中進行校驗即可

         方案三:可行,在服務端生成md5參數,並將參數作爲token傳入到頁面,頁面提交的時需要提交token及id,提交上來再用md5進行驗證一次,就知道該數據是不是頁面顯示的數據了。

 

二、垂直權限漏洞

指的是沒有對訪問接口做權限驗證。

 

發佈了109 篇原創文章 · 獲贊 10 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章