何為SQL注入
SQL注入即是指web應用程序對用戶輸入數據的合法性沒有判斷或過濾不嚴,攻擊者可以在web應用程序中事先定義好的查詢語句的結尾上添加額外的SQL語句,在管理員不知情的情況下實現非法操作,以此來實現欺騙數據庫服務器執行非授權的任意查詢,從而進一步得到相應的數據信息。
舉例:
select * from login_user where username = ? and password = ?
假如這是一個用戶登錄時的查詢語句。
如果沒有sql防注入措施,那么當攻擊者輸入 '' or 1 = 1 時,username = '' or 1 = 1 ,這條查詢語句必然會通過,導致攻擊者可以隨意登錄。
基於springboot的sql防注入過濾器
我們可以通過構建一個過濾器,過濾每個消息,如果消息是那種敏感詞匯,則過濾掉。
第一步:
新建一個SqlFilter類實現Filter接口,相應地實現Filter接口的三個方法。
第二步:
在SqlFilter類上添加兩個注解:@WebFilter @Configuration
@WebFilter(urlPatterns = "/*",filterName = "sqlFilter") :
urlPatterns:表示過濾的范圍," /* "表示過濾所有請求路徑,"/project/user/login" 則表示過濾http://localhost:8080/project/user/login這個路徑的請求。
filterName:表示這個過濾器的名稱
@Configuration:表明當前類是一個配置類。
第三步:
在springboot啟動類上增加一個注解:
@ServletComponentScan()
basePackages:過濾器的路徑。
第四步:
編寫過濾條件:在SqlFilter類繼承自Filter接口的doFilter方法中編寫過濾條件。
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { ServletRequest request = servletRequest; ServletResponse response = servletResponse; //獲得所有請求參數名 Enumeration<String> names = request.getParameterNames(); String sql = ""; while (names.hasMoreElements()){ //得到參數名 String name = names.nextElement().toString(); //得到參數對應值 String[] values = request.getParameterValues(name); for (int i = 0; i < values.length; i++) { sql += values[i]; } } if (sqlValidate(sql)){ throw new IOException("您發送請求中的參數中含有非法字符"); } else { filterChain.doFilter(request,response); } } //效驗 protected static boolean sqlValidate(String str){ String s = str.toLowerCase();//統一轉為小寫 String badStr = "select|update|and|or|delete|insert|truncate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute|table|"+ "char|declare|sitename|xp_cmdshell|like|from|grant|use|group_concat|column_name|" + "information_schema.columns|table_schema|union|where|order|by|" + "'\\*|\\;|\\-|\\--|\\+|\\,|\\//|\\/|\\%|\\#";//過濾掉的sql關鍵字,特殊字符前面需要加\\進行轉義 //使用正則表達式進行匹配 boolean matches = s.matches(badStr); return matches; }
自此,一個sql防注入過濾器就完成了。
源碼:
package com.kingpoint.kingstd.common.utils; import org.springframework.context.annotation.Configuration; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; import java.util.Enumeration; /** * @Author chenzhanfan * @Date 2021/7/19 * @Description sql防注入過濾器 */ @WebFilter(urlPatterns = "/*",filterName = "sqlFilter") @Configuration public class SqlFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { ServletRequest request = servletRequest; ServletResponse response = servletResponse; //獲得所有請求參數名 Enumeration<String> names = request.getParameterNames(); String sql = ""; while (names.hasMoreElements()){ //得到參數名 String name = names.nextElement().toString(); //得到參數對應值 String[] values = request.getParameterValues(name); for (int i = 0; i < values.length; i++) { sql += values[i]; } } if (sqlValidate(sql)){ throw new IOException("您發送請求中的參數中含有非法字符"); } else { filterChain.doFilter(request,response); } } //效驗 protected static boolean sqlValidate(String str){ String s = str.toLowerCase();//統一轉為小寫 String badStr = "select|update|and|or|delete|insert|truncate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute|table|"+ "char|declare|sitename|xp_cmdshell|like|from|grant|use|group_concat|column_name|" + "information_schema.columns|table_schema|union|where|order|by|" + "'\\*|\\;|\\-|\\--|\\+|\\,|\\//|\\/|\\%|\\#";//過濾掉的sql關鍵字,特殊字符前面需要加\\進行轉義 //使用正則表達式進行匹配 boolean matches = s.matches(badStr); return matches; } @Override public void destroy() { } }