WEB安全新玩法 [4] 防護郵箱密碼重置漏洞

大部分具有帳號系統的應用都會提供重置用戶登錄密碼的功能,常見方式之一是:用戶輸入自己的郵箱地址或手機號,應用向這個郵箱或手機號發送驗證碼,用戶將收到的驗證碼輸入應用中即可完成密碼重置。這一過程容易因設計不周全而被攻擊者加以利用。iFlow 業務安全加固平台可以為設計不當的應用打上動態虛擬修補程式,使之防禦可能的惡意利用。


以某網站為例,其郵箱密碼重置功能就存在缺陷:獲取驗證碼的郵箱和重置密碼的郵箱可以不一致。攻擊者能夠給任意郵箱所代表的用戶設置新的登錄密碼,從而冒充受害者登錄。當然,我們也會介紹如何在不修改網站源程式碼的前提下,使用 iFlow 實現業務邏輯缺陷的修補。

一、原始網站

1.1 正常用戶訪問

在密碼重置頁面,正常用戶「alice」在手機/郵箱中輸入自己的郵箱地址,如 [email protected],點擊獲取驗證碼按鈕。

圖1

網站為避免攻擊者濫用郵件發送,彈出圖形碼進行驗證。用戶正確填寫字元並確認後,網站系統後台發送郵件驗證碼到用戶「alice」的郵件地址 [email protected] 中。

圖2

用戶進入到郵件系統中收取寄給 [email protected] 的郵件,將郵件中的驗證碼和需要重置的登錄密碼填寫到表單中並提交。

圖3

網站判斷用戶輸入的郵箱驗證碼是正確的,就將 [email protected] 所代表的用戶的登錄密碼設置為新的密碼,操作成功。

各個實體的交互流程如下:

sequenceDiagram
participant 正常用戶alice
participant 瀏覽器
participant Web伺服器
participant 郵件系統
正常用戶alice->>Web伺服器: 請求:密碼重置
Web伺服器->>正常用戶alice: 顯示:密碼重置頁面
正常用戶alice->>瀏覽器: 在【手機/郵箱】中填寫alice
正常用戶alice->>瀏覽器: 點擊【獲取驗證碼】
瀏覽器->>Web伺服器: 請求:獲取圖形驗證碼
Web伺服器->>正常用戶alice: 顯示:圖形驗證碼
正常用戶alice->>瀏覽器: 輸入圖形驗證碼【字元】
瀏覽器->>Web伺服器: 發送:圖形驗證碼字元
Note over Web伺服器: 圖形驗證字元正確
Web伺服器->>郵件系統: 發送驗證碼郵件給alice
Web伺服器->>正常用戶alice: 提示:驗證碼郵件已發送
正常用戶alice->>郵件系統: 以alice收取驗證碼郵件
正常用戶alice->>瀏覽器: 輸入郵箱【驗證碼】
正常用戶alice->>瀏覽器: 輸入【設置登錄密碼】
正常用戶alice->>瀏覽器: 點擊提交【確認】
瀏覽器->>Web伺服器: 請求:確認重置密碼
Note over Web伺服器: 郵件驗證碼正確
Note over Web伺服器: 設置用戶alice的密碼
Web伺服器->>正常用戶alice: 顯示:重置密碼成功

1.2 攻擊者訪問

此處,網站在重置密碼的業務處理上有個邏輯缺陷:並未確保發送郵箱驗證碼時的郵箱地址和設置新密碼時的郵箱地址是一致的。

缺陷利用方法如下:在前面的步驟中,攻擊者「mallory」使用自己的郵箱 [email protected] 獲取驗證碼。

圖1

在收到郵箱驗證碼並正確填寫後,攻擊者「mallory」將表單中的手機/郵箱內容改為 [email protected] (之前填的是 [email protected] ),然後再填寫新的登錄密碼並提交確認。

圖3

網站判斷用戶輸入的郵箱驗證碼是正確的,就將 [email protected] 所代表的用戶的登錄密碼設置為新的密碼。如此一來,攻擊者「mallory」成功重設了受害者「alice」的密碼,並可以使用「alice」的身份登錄網站。

各個實體的交互流程如下:

sequenceDiagram
participant 攻擊者mallory
participant 瀏覽器
participant Web伺服器
participant 郵件系統
攻擊者mallory->>Web伺服器: 請求:密碼重置
Web伺服器->>攻擊者mallory: 顯示:密碼重置頁面
攻擊者mallory->>瀏覽器: 在【手機/郵箱】中填寫mallory
攻擊者mallory->>瀏覽器: 點擊【獲取驗證碼】
瀏覽器->>Web伺服器: 請求:獲取圖形驗證碼
Web伺服器->>攻擊者mallory: 顯示:圖形驗證碼
攻擊者mallory->>瀏覽器: 輸入圖形驗證碼【字元】
瀏覽器->>Web伺服器: 發送:圖形驗證碼字元
Note over Web伺服器: 圖形驗證字元正確
Web伺服器->>郵件系統: 發送驗證碼郵件給mallory
Web伺服器->>攻擊者mallory: 提示:驗證碼郵件已發送
攻擊者mallory->>郵件系統: 以mallory收取驗證碼郵件
rect rgb(250, 128, 128)
攻擊者mallory->>瀏覽器: 在【手機/郵箱】中填寫alice
end
攻擊者mallory->>瀏覽器: 輸入郵箱【驗證碼】
攻擊者mallory->>瀏覽器: 輸入【設置登錄密碼】
攻擊者mallory->>瀏覽器: 點擊提交【確認】
瀏覽器->>Web伺服器: 請求:確認重置密碼
Note over Web伺服器: 郵件驗證碼正確
rect rgb(250, 128, 128)
Note over Web伺服器: 設置用戶alice的密碼
end
Web伺服器->>攻擊者mallory: 顯示:重置密碼成功

二、iFlow虛擬修補程式後的網站

我們在 Web 伺服器前部署 iFlow 業務安全加固平台,它有能力攔截、計算和修改雙向 HTTP 報文並具備存儲能力,成為 Web 應用的虛擬修補程式。在本例中,iFlow 可保存發送驗證碼時的郵箱地址,並在之後設置密碼時將其與輸入的郵箱地址作對比,發現並制止篡改行為。

2.1 正常用戶訪問

iFlow 在圖形驗證碼通過時,將請求中的郵箱地址保存在 IP 存儲中,在設置新密碼時進行以下檢查:

  1. 該 IP 進行過發送驗證碼的操作;
  2. 該 IP 要設置密碼的郵箱地址與發送驗證碼時的郵箱相同。

各個實體的交互流程如下:

sequenceDiagram
participant 正常用戶alice
participant 瀏覽器
participant iFlow
participant Web伺服器
participant 郵件系統
正常用戶alice->>Web伺服器: 請求:密碼重置
Web伺服器->>正常用戶alice: 顯示:密碼重置頁面
正常用戶alice->>瀏覽器: 在【手機/郵箱】中填寫alice
正常用戶alice->>瀏覽器: 點擊【獲取驗證碼】
瀏覽器->>Web伺服器: 請求:獲取圖形驗證碼
Web伺服器->>正常用戶alice: 顯示:圖形驗證碼
正常用戶alice->>瀏覽器: 輸入圖形驗證碼【字元】
瀏覽器->>Web伺服器: 發送:圖形驗證碼字元
Note over Web伺服器: 圖形驗證字元正確
Web伺服器->>郵件系統: 發送驗證碼郵件給alice
Web伺服器->>iFlow: 驗證碼郵件已發送
alt the_mail不為空
iFlow->>正常用戶alice: 阻止請求
else the_mail為空
rect rgb(160, 250, 160)
Note over iFlow: 記錄郵箱地址到the_mail
end
iFlow->>正常用戶alice: 提示:驗證碼郵件已發送
end
郵件系統->>正常用戶alice: 以alice收取驗證碼郵件
正常用戶alice->>瀏覽器: 輸入郵箱【驗證碼】
正常用戶alice->>瀏覽器: 輸入【設置登錄密碼】
正常用戶alice->>瀏覽器: 點擊提交【確認】
瀏覽器->>iFlow: 請求:確認重置密碼
rect rgb(160, 250, 160)
Note over iFlow: the_mail和accounts參數:一致
Note over iFlow: 清空the_mail
end
iFlow->>Web伺服器: 請求:確認重置密碼
Note over Web伺服器: 郵件驗證碼正確
Note over Web伺服器: 設置用戶alice的密碼
Web伺服器->>正常用戶alice: 重置密碼成功

2.2 攻擊者訪問

如前所示,攻擊者在收到郵箱驗證碼之後,且未提交重設密碼之前,修改了郵箱地址。iFlow 會檢查到這個變化,依此可判斷這是一個攻擊者在訪問,於是終止此過程,不會讓系統後端真正去修改受害者的登錄密碼。

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

sequenceDiagram
participant 攻擊者mallory
participant 瀏覽器
participant iFlow
participant Web伺服器
participant 郵件系統
攻擊者mallory->>Web伺服器: 請求:密碼重置
Web伺服器->>攻擊者mallory: 顯示:密碼重置頁面
攻擊者mallory->>瀏覽器: 填寫mallory到【手機/郵箱】
攻擊者mallory->>瀏覽器: 點擊【獲取驗證碼】
瀏覽器->>Web伺服器: 請求:獲取圖形驗證碼
Web伺服器->>攻擊者mallory: 顯示:圖形驗證碼
攻擊者mallory->>瀏覽器: 輸入圖形驗證碼【字元】
瀏覽器->>Web伺服器: 發送:圖形驗證碼字元
Note over Web伺服器: 圖形驗證字元正確
Web伺服器->>郵件系統: 發送驗證碼郵件給mallory
Web伺服器->>iFlow: 驗證碼郵件已發送
alt the_mail不為空
iFlow->>攻擊者mallory: 阻止請求
else the_mail為空
rect rgb(160, 250, 160)
Note over iFlow: 記錄郵箱地址到the_mail
end
iFlow->>攻擊者mallory: 提示驗證碼郵件已發送
end
郵件系統->>攻擊者mallory: 以mallory收取驗證碼郵件
rect rgb(250, 128, 128)
攻擊者mallory->>瀏覽器: 填寫alice到【手機/郵箱】
end
攻擊者mallory->>瀏覽器: 輸入郵箱【驗證碼】
攻擊者mallory->>瀏覽器: 輸入【設置登錄密碼】
攻擊者mallory->>瀏覽器: 點擊提交【確認】
瀏覽器->>iFlow: 請求:確認重置密碼
rect rgb(160, 250, 160)
Note over iFlow: the_mail和accounts參數:不一致
end
rect rgb(250, 128, 128)
iFlow->>攻擊者mallory: 終止過程
end

2.3 程式碼

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

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

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

[
	{	
		"if": [
			"streq(REQUEST_FILENAME, '/shopx/index.php')",
			"streq(@ARGS.s, '/index/user/forgetpwdverifysend.html')"
		],
		"then": {
			"if": "REAL_IP.the_mail",
			"then": {
				"verdict": {
					"action": "deny",
					"log": "There is a user having reset password."
				}
			},
			"else": {
				"if": "contain(RESPONSE_BODY, '\"code\":0,')",
				"then": {
					"execution": "REAL_IP.the_mail@[email protected]"
				}
			}
		}
	},
	{
		"if": [
			"streq(REQUEST_FILENAME, '/shopx/index.php')",
			"streq(@ARGS.s, '/index/user/forgetpwd.html')"
		],
		"then": {
			"if": {
				"or": [
					"!REAL_IP.the_mail",
					"strne(@ARGS.accounts, REAL_IP.the_mail)"
				]
			},
			"then": {
				"verdict": {
					"action": "deny",
					"log": "Invalid ${@ARGS.accounts} access"
				}
			},
			"else": {
				"execution": "REAL_IP.the_mail=null"
			}
		}
	}
]

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

第一條規則

當伺服器返回圖形驗證結果時,iFlow 攔截此響應。如果在同一個訪問端 IP 上已經在進行重置密碼操作,則終止這次操作 (避免重複及交叉操作);否則當驗證結果為通過時,在訪問者 IP (REAL_IP) 中創建存儲變數 the_mail ,其值為用戶輸入郵箱地址。

第二條規則

當瀏覽器請求確認重置密碼時,iFlow 攔截此請求。iFlow檢查請求參數 accounts 與訪問者 IP (REAL_IP) 中存儲變數 the_mail 是否相等:如果相等則清除 the_mail ,以開放此訪問者 IP 上的重置密碼業務;如果不相等則阻止該用戶的繼續操作。

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

三、總結

iFlow 使用兩條規則在不修改伺服器端程式碼的前提下,透明地保證了重置密碼時郵箱地址的一致性。從這個例子中我們可以看到,iFlow 適合構造前後報文相關聯的複雜防護邏輯。(張戈 | 天存資訊)