WEB安全新玩法 [5] 防範水平越權之檢視他人訂單資訊

天存資訊發表於2021-06-29

水平越權是指系統中的使用者在未經授權的情況下,檢視到另一個同級別使用者所擁有的資源。水平越權會導致資訊洩露,其產生原因是軟體業務設計或編碼上的缺陷。iFlow 業務安全加固平臺可以緩解部分場景下的水平越權問題。


以某電商網站為例,其檢視訂單功能存在漏洞:僅依靠修改 URL 引數,任意登入使用者不僅可以檢視自己的訂單資訊,也可以檢視到其他使用者的訂單資訊。我們看看在網站自身存在缺陷的情況下,如何利用 iFlow 阻止水平越權的訂單資訊訪問。

一、原始網站

1.1 正常使用者訪問

正常使用者登入成功之後,進入個人中心的訂單管理頁面顯示自己的訂單列表。

圖1

從訂單列表中點選其中一個訂單的訂單詳情,則可以看到訂單的具體資訊。

圖2

HTTP 互動流程如下:

sequenceDiagram participant 正常使用者 participant 瀏覽器 participant Web伺服器 正常使用者->>瀏覽器: 點選【訂單管理】 瀏覽器->>Web伺服器: 請求:訂單管理 Web伺服器->>瀏覽器: 返回:訂單列表 瀏覽器->>正常使用者: 顯示:訂單列表頁面 正常使用者->>瀏覽器: 點選其中一項【訂單詳情】 瀏覽器->>Web伺服器: 請求:訂單詳情 Web伺服器->>瀏覽器: 返回:訂單詳情 瀏覽器->>正常使用者: 顯示:訂單詳情頁面

1.2 攻擊者訪問

電商網站在處理訂單詳情業務時有個漏洞:它使用提交引數中的訂單 ID 在資料庫中獲取到了訂單資訊,但沒有去檢查訂單所有者是否與已登入使用者為同一使用者,而是直接將訂單資訊返回給了瀏覽器。

這樣,攻擊者與正常使用者經過同樣的操作 (即在訂單列表檢視自己的訂單詳情) 後,可以手工修改 URL 中的訂單 ID 從而獲取到任意使用者的訂單資訊。這個過程可以連續地進行。

下圖中,攻擊者訪問了 ID 為 8 的訂單詳情,而這個訂單本應屬於「test01」使用者。

圖3

HTTP 互動流程如下:

sequenceDiagram participant 攻擊者 participant 瀏覽器 participant Web伺服器 攻擊者->>瀏覽器: 點選【訂單管理】 瀏覽器->>Web伺服器: 請求:訂單管理 Web伺服器->>瀏覽器: 返回:訂單列表 瀏覽器->>攻擊者: 顯示:訂單列表頁面 攻擊者->>瀏覽器: 點選其中一項【訂單詳情】 瀏覽器->>Web伺服器: 請求:訂單詳情 Web伺服器->>瀏覽器: 返回:訂單詳情 瀏覽器->>攻擊者: 顯示:自己的訂單詳情頁面 rect rgb(250, 128, 128) 攻擊者->>瀏覽器: 請求引數id修改為任意值 end 瀏覽器->>Web伺服器: 請求:訂單詳情 Web伺服器->>瀏覽器: 返回:訂單詳情 rect rgb(250, 128, 128) 瀏覽器->>攻擊者: 顯示:他人的訂單詳情頁面 end

二、iFlow虛擬補丁後的網站

我們在 Web 伺服器前部署 iFlow 業務安全加固平臺,它有能力攔截、計算和修改雙向 HTTP 報文並具備儲存能力,成為 Web 應用的虛擬補丁。在本例中,iFlow 記錄訂單列表中的所有訂單 ID,在使用者訪問訂單詳情時進行檢查。

2.1 正常使用者訪問

伺服器在返回使用者訂單列表時,iFlow 解析出每一訂單專案的訂單 ID 形成使用者的 合法id記錄。使用者在訪問訂單詳情時,iFlow 檢查要訪問的訂單 ID 是否包含在 合法id記錄 中。

正常使用者的 HTTP 互動流程如下:

sequenceDiagram participant 正常使用者 participant 瀏覽器 participant iFlow participant Web伺服器 正常使用者->>瀏覽器: 點選【訂單管理】 瀏覽器->>Web伺服器: 請求:訂單管理 Web伺服器->>iFlow: 返回:訂單列表 rect rgb(160, 250, 160) Note over iFlow: 所有訂單id形成合法id記錄 end iFlow->>瀏覽器: 返回:訂單列表 瀏覽器->>正常使用者: 顯示:訂單列表頁面 正常使用者->>瀏覽器: 點選其中一項【訂單詳情】 瀏覽器->>iFlow: 請求:訂單詳情 rect rgb(160, 250, 160) Note over iFlow: 訂單id在合法id記錄中 end iFlow->>Web伺服器: 請求:訂單詳情 Web伺服器->>瀏覽器: 返回:訂單詳情 瀏覽器->>正常使用者: 顯示:訂單詳情頁面

2.2 攻擊者訪問

如前所示,攻擊者自行修改訂單 ID 發出請求,iFlow 攔截此請求,發現請求的 ID 不在 合法id記錄 中,即終止此過程。

攻擊者的 HTTP 協議互動過程如下:

sequenceDiagram participant 攻擊者 participant 瀏覽器 participant iFlow participant Web伺服器 攻擊者->>瀏覽器: 點選【訂單管理】 瀏覽器->>Web伺服器: 請求:訂單管理 Web伺服器->>iFlow: 返回:訂單列表 rect rgb(160, 250, 160) Note over iFlow: 所有訂單id形成合法id記錄 end iFlow->>瀏覽器: 返回:訂單列表 瀏覽器->>攻擊者: 顯示:訂單列表頁面 攻擊者->>瀏覽器: 點選其中一項【訂單詳情】 瀏覽器->>iFlow: 請求:訂單詳情 rect rgb(160, 250, 160) Note over iFlow: 訂單id在合法id記錄中 end iFlow->>Web伺服器: 請求:訂單詳情 Web伺服器->>瀏覽器: 返回:訂單詳情 瀏覽器->>攻擊者: 顯示:訂單詳情頁面 rect rgb(250, 128, 128) 攻擊者->>瀏覽器: 請求引數id修改為任意值 end 瀏覽器->>iFlow: 請求:訂單詳情 rect rgb(160, 250, 160) Note over iFlow: 訂單id不在合法id記錄中 end iFlow->>瀏覽器: 返回:終止訪問 rect rgb(250, 128, 128) 瀏覽器->>攻擊者: 終止訪問 end

2.3 程式碼

iFlow 內建的 W2 語言是一種專門用於實現 Web 應用安全加固的類程式語言。它介於配置和通用語言之間,具備程式設計的基本要素和針對 HTTP 協議的特有擴充套件,能為業務系統編寫涉及複雜判斷和動態修改的邏輯。

考慮到安全產品的使用者通常為非程式設計師,他們習慣面對配置檔案而非一段程式碼。因此,W2 語言雖包含語言要素,仍以規則檔案方式呈現,並採用可以體現層次結構和方便詞法校驗的 JSON 格式。

用 W2 語言實現上述虛擬補丁的程式碼如下:

[
	{
        "if": [
			"streq(REQUEST_FILENAME, '/shopx/index.php')",
			"streq(@ARGS.s, '/index/order/index.html')"
		],
		"then": {
            "execution": { 
                "directive": "setVariable", 
                "variable": "SESSION.valid_ids", 
                "value": "rxMatch(RESPONSE_BODY, '<a[^>]+href=\"[^\"].*(/index/order/detail/id.*)\" target=.*\"[^>]*>', -1, 1)",
                "expiry": 3600
            } 
        }
    },
    {
        "if": [ 
            "streq(REQUEST_FILENAME, '/shopx/public/index.php')",
            "contain(@ARGS.s, '/index/order/detail/id')",
            "!contain(SESSION.valid_ids, @ARGS.s)",
        ],
        "then": { 
            "verdict": { 
                "action": "deny", 
                "log": "User access page ${@ARGS.s} NOT in ${SESSION.valid_ids}" 
            } 
        } 
    }
]

示例程式碼中有兩條規則,分別作用如下:

第一條規則

當伺服器返回訂單列表時,iFlow 解析此響應。iFlow 用正規表示式匹配列表中每一個訂單詳情的連結,然後儲存在會話 (SESSION) 的儲存變數 valid_ids 中。

第二條規則

當瀏覽器請求訂單詳情時,iFlow 攔截此請求。iFlow 檢查請求引數 s 是否包含在會話 (SESSION) 的儲存變數 valid_ids 中。如果沒有,則表示這個訂單 ID 是攻擊者自行輸入的,阻止訪問。

注意:上述會話中的 valid_ids 是儲存在伺服器端的 iFlow 儲存中的,攻擊者在瀏覽器端是看不到資料更無法進行修改的。


三、總結

iFlow 使用兩條規則在不修改伺服器端程式碼的前提下,利用沒有越權的訂單列表資訊,透明地保證了訂單詳情不被水平越權檢視。

這個例子是建立在使用者常規操作順序的基礎上的,即先獲得訂單列表再檢視訂單詳情。如果網站的其他頁面也包含了訂單詳情連結或者使用者從書籤中訪問訂單詳情,則會產生誤判。因此,它僅適用於這個場景而非徹底解決了水平越權問題。

以補丁方式解決水平越權問題還可以有其他一些方式,如後端引數混淆、加入鑑別碼等方式。如何用 iFlow 實現這些功能,在後續介紹中可以看到。(張戈 | 天存資訊)

相關文章