sql注入解決方案
前言: 前幾天公司進行滲透測試 發現了sql注入的問題,然後發現是有人使用了 $ ,然後看了他的代碼發現了問題,最主要的原因就是懶,本來應該讓前端傳list集合,他卻讓前端拼字符串直接in(入參) ,然後我和項目經理考慮了,項目已經上線了,如果改入參還要重新聯調接口,現在還有個新項目準備開發,抽不出來人進行修改聯調了,便在內部扭轉,進行操作,最後梳理成文檔幫助公司同事解決這個問題。
mybatis Sql:
<if test="safetyPageParam.caseStatus !=null and safetyPageParam.caseStatus != ''">
AND t2.channel_status in (${safetyPageParam.caseStatus})
</if>
問題: 使用 $, 會引發SQL注入問題,其實是有點
入參:
“safetyPageParam.caseStatus”:"(select 7445 from (select(sleep(5)))xGHL)"
執行sql:
SELECT count(0) FROM sheet_report_info t1
LEFT JOIN (SELECT * FROM t_case_info WHERE is_del = 0) t2
ON t1.report_no = t2.report_no
LEFT JOIN (SELECT * FROM t_policy_info WHERE is_del = 0) t3
ON t1.report_no = t3.report_no
WHERE t1.channel_code = 'safety' AND t1.is_del = 0
AND t1.reg_user_code = '19UC1485196736019300352'
AND t2.channel_status IN (
(SELECT 7445 FROM (SELECT (sleep(5))) xGHL) // 注入sql
)
AND t2.channel_code = 'safety'
解決辦法:
對於 in 操作的sql語句不能簡單的將 $ 替代爲 #。這樣雖然規避了sql注入,但引發程序功能的不正確。
入參:
{
"caseNo": "",
"caseStatus": "'01','02'", // 前端傳值,爲了多選
"channelCode": "safety",
"closeAuditorCode": "",
"desc": false,
"endReportTime": "",
"endRiskTime": "",
"insuredCompanyReportNo": "",
"orderBy": "report_time",
"pn": 1,
"policyNo": "",
"ps": 10,
"regUserCode": "19UC1485196736019300352",
"reportNo": "",
"servicerCode": "",
"startReportTime": "",
"startRiskTime": "",
"u400Code": ""
}
爲了達到多選 caseStatus,目前前端傳值爲String,內容爲 " ‘01’,‘02’ ".
如果使用
t2.channel_status in (#{safetyPageParam.caseStatus})
則語義爲
channel_status in ( " ‘01’,‘02’ ") 一個參數,參數值爲 { ‘01’,‘02’ }
這樣程序功能是錯誤的。
方案
java端將 ‘01’,‘02’ 進行 split(",")處理,轉爲list。
mybatis寫法改爲
<if test="safetyPageParam.listCaseStatus !=null and safetyPageParam.listCaseStatus.size > 0">
AND t2.channel_status in
<foreach collection="safetyPageParam.listCaseStatus" item="status" index="index" open="(" close=")" separator=",">
#{status}
</foreach>
</if>
每天記錄發現的問題,不進步就是在退步