本篇是之前安全漏洞整改系列(一)的延續,也是終結篇,希望通過這兩篇內容帶給大家一些關於安全問題的體驗和重視,不至於漏洞真正來臨的時候手忙腳亂,就像前幾天的log4j2一夜間讓多少程式設計師又白了頭,寬了衣帶。
圖片拍攝於西安太奧海洋館
問題4:反射性xss儲存
漏洞等級:高危
漏洞詳情:存在xss漏洞,可以將惡意指令碼執行到合法網站或者Web應用程式中,漏洞驗證截圖如下
漏洞危害:攻擊者可以偽造網站連結,誘導他人點選,獲取關鍵資訊,如session竊取等。
說下這裡的tabs2是做什麼用的,這是一個Controller方法,對應的檢視是一個velocity頁面,Controller解析url引數進行一些處理返回給velocity頁面。
Controller setAttribute("tabsParams",tabsParams); velocity <script> tabsParams= "$!tabsParams"; </script>
這個訪問連結為什麼會造成xss呢?
tabs2?;9805";;alert(document.cookie);"9688
velocity是一種模板引擎,最終返回給瀏覽器的還是html,我們看下最終生成的產物是什麼樣的。
<script> tabsParams = "&;9805";;alert(document.cookie);"9688=null"; </script>
看到這兒其實已經很明顯了,;9805";;alert(document.cookie);"9688這一串內容前後兩個雙引號很巧妙的破壞了原來js的語義,本來只是一個普通的賦值語句,現在卻變成了三條js語句,其中就包含那條邪惡的alert(document.cookie);
解決辦法和之前很相似,對返回給前端的內容做充分轉義,這裡我使用的是org.owasp.encoder這個轉義庫,這個轉義庫針對多種上下文提供了很好的支援,使用的時候要區別對待,不能一概而論,否則會誤殺。
Encode.forJavaScript(tabsParams);
對比看下,轉義前後返回到前端的內容有何區別
轉義前:
<script> tabs = "&;9805";;alert(document.cookie);"9688=null"; </script>
轉義後:
tabs = "\x26;9805\x22;;alert(document.cookie);\x229688=null";
可以看到字串被轉義成了\x22,保護了原有的執行語義。
問題5:sql注入
漏洞等級:高危
漏洞詳情:***/findPage介面存在SQL隱碼攻擊漏洞
漏洞危害:攻擊者能夠直接獲取資料庫操作許可權,檢視使用者資訊下載使用者資料
findPage介面是一個分頁介面,會接收一個sortField欄位,這個sortField最終會反映到SQL語句中,起到動態調整排序列的效果。
比如以下SQL語句:
select * from user order by ${sortField}
${sortField}會被替換為傳入的值,比如age、name這些正常的值,還有一些非正常的值,比如1 and (SELECT 1271 from (select (sleep(10)))Ssvo),看下最後這個替換完會呈現什麼效果
SELECT * FROM test.user ORDER BY 1 AND (SELECT 1271 FROM (SELECT (SLEEP(10))) Ssvo)
最終執行的效果就是睡眠10s,想象下如果有成百上千個sleep在資料庫執行,我們的業務系統會怎樣。
聰明的你也許會說為什麼不用預編譯解決這種SQL隱碼攻擊呢,在這種場景之下其實是不能使用預編譯的,order by後面需要一個確切的列名,如果是問號,那SQL解析階段就會報語法錯誤,那有什麼辦法可以解決呢?
1.控制sortField為一個有限的集合,不要直接替換到SQL中,增加一層判斷
if(sortField.equals("age")){ sql.replace(${sortField},"age"); }else if(sortField.equals("name")){ sql.replace(${sortField},"name"); }else { throw Exception("不支援的排序列"); }
2.對sortField執行過濾,限制只能是數字、字母、下劃線
sortField.replace("[^a-zA-Z0-9_\s+]", "");
問題6:任意使用者密碼重置
漏洞等級:高危
漏洞詳情:忘記密碼時,先輸入一個已經存在的手機號,點選傳送簡訊驗證碼,攻擊者隨意輸入6位字元,點選下一步,攔截響應包,篡改為true,進入到設定新密碼頁面
漏洞危害:重置任意使用者密碼
下面是目前重置密碼的流程
1.驗證手機號碼是否存在;
2.後臺傳送驗證碼;
3.校驗驗證碼是否正確;
4.修改新密碼;
這個漏洞也是一些多步操作容易遺漏的,後面的環節沒有在後臺校驗前面步驟的合法性,就拿這個場景來說,真正修改密碼時應該後臺再校驗前一步驗證碼的狀態,防止攻擊者繞過前端校驗。
改造後的流程如下:
1.驗證手機號碼是否存在;
2.後臺傳送驗證碼;
3.校驗驗證碼是否正確,並記錄驗證碼狀態;
4.後臺校驗前一步驗證碼狀態,如果合法,修改新密碼
推薦閱讀
1.阿里技術-如何避免出現SQL隱碼攻擊漏洞
https://mp.weixin.qq.com/s/mP49OCkwqSnamtop0cChdQ
安全問題無小事,以上兩篇是我近期負責整改的一些安全漏洞的記錄,希望能給大家帶來些許幫助,後續如果還有這方面的內容會繼續輸出,我對安全領域也是小白一枚,以上內容如有紕漏,歡迎指正。