安全漏洞整改系列(二)

踩刀詩人發表於2021-12-21

本篇是之前安全漏洞整改系列(一)的延續,也是終結篇,希望通過這兩篇內容帶給大家一些關於安全問題的體驗和重視,不至於漏洞真正來臨的時候手忙腳亂,就像前幾天的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

 

安全問題無小事,以上兩篇是我近期負責整改的一些安全漏洞的記錄,希望能給大家帶來些許幫助,後續如果還有這方面的內容會繼續輸出,我對安全領域也是小白一枚,以上內容如有紕漏,歡迎指正。

 

 

 

 

相關文章