水平越權是指系統中的用戶在未經授權的情況下,查看到另一個同級別用戶所擁有的資源。水平越權會導致信息泄露,其產生原因是軟件業務設計或編碼上的缺陷。iFlow 業務安全加固平台可以緩解部分場景下的水平越權問題。
以某電商網站為例,其查看訂單功能存在漏洞:僅依靠修改 URL 參數,任意登錄用戶不僅可以查看自己的訂單信息,也可以查看到其他用戶的訂單信息。我們看看在網站自身存在缺陷的情況下,如何利用 iFlow 阻止水平越權的訂單信息訪問。
一、原始網站
1.1 正常用戶訪問
正常用戶登錄成功之后,進入個人中心的訂單管理頁面顯示自己的訂單列表。
從訂單列表中點擊其中一個訂單的訂單詳情,則可以看到訂單的具體信息。
HTTP 交互流程如下:
1.2 攻擊者訪問
電商網站在處理訂單詳情業務時有個漏洞:它使用提交參數中的訂單 ID 在數據庫中獲取到了訂單信息,但沒有去檢查訂單所有者是否與已登錄用戶為同一用戶,而是直接將訂單信息返回給了瀏覽器。
這樣,攻擊者與正常用戶經過同樣的操作 (即在訂單列表查看自己的訂單詳情) 后,可以手工修改 URL 中的訂單 ID 從而獲取到任意用戶的訂單信息。這個過程可以連續地進行。
下圖中,攻擊者訪問了 ID 為 8 的訂單詳情,而這個訂單本應屬於「test01」用戶。
HTTP 交互流程如下:
二、iFlow虛擬補丁后的網站
我們在 Web 服務器前部署 iFlow 業務安全加固平台,它有能力攔截、計算和修改雙向 HTTP 報文並具備存儲能力,成為 Web 應用的虛擬補丁。在本例中,iFlow 記錄訂單列表中的所有訂單 ID,在用戶訪問訂單詳情時進行檢查。
2.1 正常用戶訪問
服務器在返回用戶訂單列表時,iFlow 解析出每一訂單項目的訂單 ID 形成用戶的 合法id記錄
。用戶在訪問訂單詳情時,iFlow 檢查要訪問的訂單 ID 是否包含在 合法id記錄
中。
正常用戶的 HTTP 交互流程如下:
2.2 攻擊者訪問
如前所示,攻擊者自行修改訂單 ID 發出請求,iFlow 攔截此請求,發現請求的 ID 不在 合法id記錄
中,即終止此過程。
攻擊者的 HTTP 協議交互過程如下:
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 實現這些功能,在后續介紹中可以看到。(張戈 | 天存信息)