在完成關鍵業務操作時,要求使用者輸入圖形驗證碼是防範自動化攻擊的一種措施。為安全起見,即使針對同一使用者,在重新輸入資訊時也應該更新圖形驗證碼。iFlow 業務安全加固平臺可以加強這方面的處理。
某網站系統在登入時要求使用者輸入圖形驗證碼。如果賬號資訊錯誤並得到系統提示後,使用者重新輸入賬號資訊時,仍可使用原來的圖形驗證碼。我們看看如何利用 iFlow 使得圖形驗證碼每次都得到更新。
一、原始網站
1.1 正常使用者訪問
使用者在登入時輸入了正確的圖形驗證碼字元,如果提交的賬號資訊有誤,系統提示登入錯誤。
使用者仍使用原來的圖形驗證碼字元,提交了正確的賬號資訊後,系統提示登入成功。
HTTP 互動流程如下:
participant 正常使用者
participant 瀏覽器
participant Web伺服器
正常使用者->>瀏覽器: 賬號、錯誤的密碼、驗證碼
瀏覽器->>Web伺服器: 請求:登入
Web伺服器->>瀏覽器: 返回:登入失敗
瀏覽器->>正常使用者: 顯示:登入失敗
正常使用者->>瀏覽器: 賬號、正確的密碼、原來的驗證碼
瀏覽器->>Web伺服器: 請求:登入
Web伺服器->>瀏覽器: 返回:登入成功
瀏覽器->>正常使用者: 顯示:登入成功
1.2 攻擊者訪問
使用者登入失敗,網站沒有主動更新圖形驗證碼,而是一段時間內仍接受這個驗證碼。這個特性具有使用者友好性,但增加了安全風險。
這樣,攻擊者即使沒有使用圖形驗證碼識別工具,也可以在人工識別出驗證碼後,在驗證碼過期時間之內,使用工具進行多次的撞庫請求,並記錄下成功登入的賬號密碼組合。
HTTP 互動流程如下:
participant 攻擊者
participant 瀏覽器
participant 攻擊工具
participant Web伺服器
攻擊者->>瀏覽器: 賬號、錯誤的密碼、驗證碼
瀏覽器->>Web伺服器: 請求:登入
Web伺服器->>瀏覽器: 返回:登入失敗
瀏覽器->>攻擊者: 顯示:登入失敗
loop 驗證碼超時時間內
rect rgb(250, 128, 128)
攻擊者->>攻擊工具: 不同的賬號/密碼對
end
攻擊工具->>Web伺服器: 請求:登入
Web伺服器->>攻擊工具: 返回:登入結果
rect rgb(250, 128, 128)
攻擊工具->>攻擊者: 記錄登入成功的賬號/密碼對
end
end
二、iFlow虛擬補丁後的網站
我們在 Web 伺服器前部署 iFlow 業務安全加固平臺,它有能力攔截、計算和修改雙向 HTTP 報文並具備儲存能力,成為 Web 應用的虛擬補丁。在本例中,iFlow 記錄所有出現過的驗證碼,不允許使用者重複使用這些驗證碼。
2.1 正常使用者訪問
iFlow 不允許使用重複的驗證碼。正常使用者登入失敗後,需要重新整理頁面或重新整理驗證碼再進行登入。使用者如果使用相同的驗證碼,iFlow 會自動重新整理頁面併產生新的驗證碼,使用者需要輸入新的驗證碼進行登入。
正常使用者的 HTTP 互動流程如下:
participant 正常使用者
participant 瀏覽器
participant iFlow
participant Web伺服器
正常使用者->>瀏覽器: 賬號、錯誤的密碼、驗證碼
瀏覽器->>iFlow: 請求:登入
Note over iFlow: 驗證碼不在used_vcode中
Note over iFlow: 將驗證碼加入到used_vcode中
iFlow->>Web伺服器: 請求:登入
Web伺服器->>瀏覽器: 返回:登入失敗
瀏覽器->>正常使用者: 顯示:登入失敗
正常使用者->>瀏覽器: 賬號、正確的密碼、舊的驗證碼
瀏覽器->>iFlow: 請求:登入
Note over iFlow: 驗證碼在used_vcode中
iFlow->>瀏覽器: 返回:重定向頁面
瀏覽器->>Web伺服器: 請求:新登入頁面
Web伺服器->>瀏覽器: 返回:新驗證碼的登入頁面
瀏覽器->>正常使用者: 顯示:新驗證碼的登入頁面
正常使用者->>瀏覽器: 賬號、正確的密碼、新的驗證碼
瀏覽器->>iFlow: 請求:登入
Note over iFlow: 驗證碼不在used_vcode中
Note over iFlow: 將驗證碼加入到used_vcode中
iFlow->>Web伺服器: 請求:登入
Web伺服器->>瀏覽器: 返回:登入成功
瀏覽器->>正常使用者: 顯示:登入成功
2.2 攻擊者訪問
如前所示,攻擊者首次人工識別出驗證碼後,用攻擊工具連續發出相同驗證碼的不同賬號/密碼組合去嘗試登入。iFlow 攔截這些請求,發現驗證碼已使用過,則返回 302 重定向響應。鑑別過程並未在 Web 伺服器上進行,攻擊者得不到鑑別結果。
攻擊者的 HTTP 協議互動過程如下:
participant 攻擊者
participant 瀏覽器
participant 攻擊工具
participant iFlow
participant Web伺服器
攻擊者->>瀏覽器: 賬號、錯誤的密碼、驗證碼
瀏覽器->>iFlow: 請求:登入
Note over iFlow: 驗證碼不在used_vcode中
Note over iFlow: 將驗證碼加入到used_vcode中
iFlow->>Web伺服器: 請求:登入
Web伺服器->>瀏覽器: 返回:登入失敗
瀏覽器->>攻擊者: 顯示:登入失敗
loop 驗證碼超時時間內
rect rgb(250, 128, 128)
攻擊者->>攻擊工具: 不同的賬號/密碼對
end
攻擊工具->>iFlow: 請求:登入
Note over iFlow: 驗證碼在used_vcode中
iFlow->>攻擊工具: 返回:重定向頁面
rect rgb(250, 128, 128)
攻擊工具->>攻擊者: 得不到登入是否成功的資訊
end
end
2.3 程式碼
iFlow 內建的 W2 語言是一種專門用於實現 Web 應用安全加固的類程式語言。它介於配置和通用語言之間,具備程式設計的基本要素和針對 HTTP 協議的特有擴充套件,能為業務系統編寫涉及複雜判斷和動態修改的邏輯。
考慮到安全產品的使用者通常為非程式設計師,他們習慣面對配置檔案而非一段程式碼。因此,W2 語言雖包含語言要素,仍以規則檔案方式呈現,並採用可以體現層次結構和方便詞法校驗的 JSON 格式。
用 W2 語言實現上述虛擬補丁的程式碼如下:
{
"if": [
"streq(REQUEST_FILENAME, '/shopx/index.php')",
"streq(@ARGS.s, '/index/user/login.html')"
],
"then": {
"if": "contain(SESSION.used_vcode, @ARGS.verify)",
"then": {
"verdict": {
"action": "redirect",
"param": "/shopx/index.php?s=/index/user/logininfo.html",
"log": "user ${SESSION.user} reuse verify code."
}
},
"else": "SESSION.used_vcode@600 = SESSION.used_vcode .. ',' .. @ARGS.verify"
}
}
示例程式碼只有一條規則,它使用儲存變數 used_vcode
記錄所有已使用的驗證碼。當有登入請求時,規則判斷驗證碼請求引數 verify
是否在本會話 (SESSION) 的儲存變數 used_vcode
中存在:
- 如果存在:表明此請求重用了驗證碼,直接返回重定向到登入頁面的響應。
- 如果不存在:表明此請求使用新的驗證碼,將驗證碼加入到本會話 (SESSION) 的儲存變數
used_vcode
中,繼續進行實際的登入鑑別過程。
注意:上述會話中的
used_vcode
是儲存在伺服器端的 iFlow 儲存中的,攻擊者在瀏覽器端是看不到資料更無法進行修改的。
三、總結
iFlow 使用一條規則就可以在不改動後端程式的情形下,避免使用者使用重複的驗證碼。
需要說明的是,文中的解決方案僅是一個示例,其一定程度上影響了人機互動的流暢性。而 iFlow 是一種靈活的類程式語言,使用它應該能寫出更完善的處理流程。(張戈 | 天存資訊)