摘要:在距離“等待頁面”模塊(因為是雙十一的關鍵模塊,安全起見故用這個名稱來替代)上線時間還剩2天的時候,接到了該模塊的功能測試任務。在簡單了解模塊功能需求之后發現,如果選擇現有的自動化測試工具來測試,將存在不少的盲點(最終bug記錄,也證明了這點),但是在這么短的時間內不可能自己設計和改造工具,因此當前最高效且質量覆蓋最好的方法,將會是手工測試的方式。
模塊功能需求:
該模塊的功能需求非常簡單,只有2點。
1. 流程需求:
當用戶訪問,觸發攔截引擎的攔截規則(訪問過于頻繁)后,前端web服務器(Tengine)將用戶的請求轉入“等待頁面”模塊的處理邏輯,“等待頁面”模塊將用戶正常的請求(GET或POST表單請求)進行保存并返回用戶一個倒計時頁面(倒計時時間可配置)。當倒計時結束后,倒計時頁面內的js代碼觸發瀏覽器自動重新提交用戶的請求到其最初的url地址(會帶上用戶原始的GET或POST請求)。如果重試成功,則正常返回用戶的請求內容,如果重試失敗(再次觸發攔截規則),則再次進入等待頁面,如果連續重試n(可配)次后,依然失敗,則返回失敗頁面(告訴用戶,對不起系統繁忙無法響應您的請求,請返回或前往其他地址)。
2. 數據轉發需求:
要求,在經過“等待頁面”模塊的邏輯處理后,用戶請求的數據不能丟失和新增,保證用戶在完成倒計時的等待時間后,能正常的重新訪問最初的url。
現有的自動化測試工具的弊端及盲點:
用于web服務器的自動化測試工具,最常用的有1. HttpClient,2. Curl, 3. Perl, 4. Selenium 等。
他們的弊端和盲點分別在于:
1. 難于模擬訪問過于頻繁從而觸發攔截規則;
因為該攔截規則具有一點的模糊性,無法明確究竟連續發送幾次請求能夠觸發攔截規則,而且如果一味的采用多發請求的方式,將于跳過倒計時頁面,從而導致邏輯流程跳躍的問題;
2. 無法實現倒計時頁面的自動觸發瀏覽器重新提交用戶請求的功能;
因為對于基于請求發送,然后驗證響應的測試工具,如HttpClient, Curl和Perl,他們所能獲得的響應,只能達到獲取倒計時頁面這一步,無法讓倒計時頁面內的js腳本生效觸發二次訪問。而且雖然可以通過驗證倒計時頁面內的js代碼來判斷數據轉發是否正確,但是有幾處bug顯示,即使第一經過倒計時頁面的時候,數據能夠完整的保存,但是由于“等待頁面”模塊的編碼問題,導致第二次經過倒計時頁面的時候,數據被重復編碼導致數據篡改和新增的情況。
3. 無法獲取響應信息;
看完第二點的時候,你會說,come on 用Selenium吧,它能模擬鼠標動作,能夠操作瀏覽器行為。但是,恰巧Selenium無法獲取Resposne Header,Query String Parameters, Request Payload, Form Data等信息,這也就無法驗證數據是否完整轉發了。
4. 容易忽略連續重試和失敗頁面的驗證;
從幾處bug的發現看出,采用自動化測試,容易忽略測試連續重試失敗的過程及這之間的數據完整轉發的需求,而且很少會將測試進行到返回失敗頁面這一步。
5. 容易忽略細微的變化;
采用自動化測試,容易忽略每次重試之間的細節變化,如參數順序和數量的變化,數據編碼的前后變化等。
手工測試過程:
手工測試過程其實也非常簡單:
首先準備測試工具:
1. 能夠發送GET(自定義URL參數和Request Header)和POST(自定義URL參數,Form Data, Upload FileData, Request Header)請求的HTML文件。
2. 后端JBoss上的Servlet,負責將請求發送過來的所有數據通過Response返回回瀏覽器,便于測試時的請求數據驗證。
其次通過瀏覽器加載HTML文件并設置測試點之后發送請求,不斷刷新訪問觸發攔截規則,觀察每次經過“等待頁面”模塊處理,跳轉到倒計時頁面后重新觸發瀏覽器執行用戶請求及最后觸發失敗頁面的前后請求數據是否一致,流程是否正常。
測試點包括正常邏輯,異常邏輯,空數據,特殊字符,XSS攻擊字符等
bug匯總分析:
本次測試共發現7處bug,2處風險點,鑒于安全考慮,此處就總結幾處典型的BUG,風險點咱就不說了。
1. 經過“等待頁面”模塊處理之后,POST請求所攜帶的URL參數丟失問題:
該問題是由于模塊在處理POST請求的數據存儲時,沒正確保存數據長度,導致數據遺失;
2. POST的表單數據,攜帶特殊字符,如<,>,/,&等,經過“等待頁面”模塊處理之后,轉譯錯誤,如轉譯后的字符不完整,轉譯后的字符經過第二次模塊處理之后,再次轉譯:
該問題是由于模塊的轉譯代碼1. 在轉譯之后沒正確保存轉譯數據長度;2. 沒正確區分轉譯內容,導致多次轉譯;
3. POST的表單數據,攜帶特殊字符,如空格,中文等,經過“等待頁面”模塊處理之后,出現編碼錯誤,如第一次經過模塊處理后,空格邊encode成“+”,第二次經過模塊處理后,繼續encode“+”成為“%2B”,導致最后后端Server接收并deconde得到的數據是“+”而不是最初的空格;
該問題是由于模塊的encode代碼,使用了錯誤的參數設置,正確的做法是:ngx_unescape_uri函數調用時設置參數 NGX_UNESCAPE_WWW_FORM
4. 對不支持的POST數據,直接丟棄POST Data 并強制轉換content type為application/x-www-form-urlencoded:
該問題是由于模塊對于不支持的POST數據,采用粗暴的處理方案導致的。