簡介
SQL注入就是客戶端在向服務器發送請求的時候,sql命令通過表單提交或者url字符串拼接傳遞到后台持久層,最終達到欺騙服務器執行惡意的SQL命令;
實踐
項目中如何防止sql注入呢,有以下三點:
- 前端表單進行參數格式控制;
- 后台進行參數格式化,過濾所有涉及sql的非法字符;
//參考:https://freeman983.iteye.com/blog/1153989
//過濾 '
//ORACLE 注解 -- /**/
//關鍵字過濾 update,delete
static String reg = "(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|"
+ "(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)\\b)";
static Pattern sqlPattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);//表示忽略大小寫
/***************************************************************************
* 參數校驗
*
* @param str ep: "or 1=1"
*/
public static boolean isSqlValid(String str) {
Matcher matcher = sqlPattern.matcher(str);
if (matcher.find()) {
System.out.println("參數存在非法字符,請確認:"+matcher.group());//獲取非法字符:or
return false;
}
return true;
}
- 持久層使用參數化的持久化sql,使用預編譯語句集,切忌使用拼接字符串;
String sql= "select * from user where name=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, name);
ResultSet rs = ps.executeQuery();
2. mybatis防止sql注入
myatis是一款優秀的持久層框架,在防止sql注入方面,mybatis啟用了預編譯功能,在所有的SQL執行前,
都會先將SQL發送給數據庫進行編譯,執行時,直接替換占位符"?"即可;
mybatis在處理傳參的時候,有兩種處理方式,一種是#,另一種是$;
- #{XXX},將傳入參數都當成一個字符串,會自動加雙引號,已經經過預編譯,安全性高,能很大程度上防止sql注入;
- ${XXX},該方式則會直接將參數嵌入sql語句,未經過預編譯,安全性低,無法防止sql注入;
總結
在項目中我們一般都會對sql的參數進行多重的限制,同時多提高代碼的規范和質量,多使用預編譯功能,這樣才能更大程度去防范sql注入