2019-08-23/防sql注入過濾器

現(xiàn)在后端的框架也做了防止sql注入的手段慨畸,比如使用PreparedStatement+占位符莱坎。但加一層過濾器總歸更加安全一點。這里的防sql注入的過濾器可以對普通get/post請求進行參數(shù)過濾寸士,也可以對post+application/json等請求進行參數(shù)過濾檐什。
該過濾器使用了請求的包裝類,具體參考我的上一篇文章http://www.reibang.com/p/579558b6dc63
弱卡,這里只給出過濾參數(shù)的部分:

package cn.wjp.mydaily.common.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;

import javax.servlet.FilterConfig;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;

/**
 * 防止SQL注入的攔截器  放在xssFilter之后   xssFilter轉(zhuǎn)義之后的字符會被該過濾器當(dāng)作sql注入
 * @author
 * @time 20190425
 */
public class SqlInjectFilter implements Filter {

    /**
     * 需要過濾的sql關(guān)鍵字乃正,可以手動添加
     */
    public static final String BAD_PARAM_STR ="'|and|exec|execute|insert|select|delete|update|count|drop|*|%|chr|mid|master|truncate|" +
            "char|declare|sitename|net user|xp_cmdshell|;|or|-|+|,|like'|and|exec|execute|insert|create|drop|" +
            "table|from|grant|use|group_concat|column_name|" +
            "information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|*|" +
            "chr|mid|master|truncate|char|declare|or|;|-|--|+|,|like|//|/|%|#";

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request =(HttpServletRequest)req;
        HttpServletResponse response =(HttpServletResponse)res;

        String contentType = request.getContentType();//獲取contentType請求頭
        String method = request.getMethod();//獲取請求方法  post/get
        //1 處理get請求  get請求的Content-Type一般為application/x-www-form-urlencoded  或者  text/html
        if(method.trim().equalsIgnoreCase(HttpConst.GET_METHOD)){
            if(isValidParamForGet(request)){
                chain.doFilter(request, response);
                return;
            }else {
                response.sendError(403,"發(fā)送的參數(shù)可能會引起sql注入,系統(tǒng)拒絕服務(wù)婶博!");
                return;
            }

        }
        //2 處理post請求  只處理application/x-www-form-urlencoded  application/json,對于multipart/form-data瓮具,直接放行
        if(method.trim().equalsIgnoreCase(HttpConst.POST_METHOD)){
            if(contentType.trim().toLowerCase().contains(HttpConst.MULTIPART_CONTENT_TYPE)){
                chain.doFilter(request, response);
                return;
            }
            //處理application/x-www-form-urlencoded
            if(contentType.trim().toLowerCase().contains(HttpConst.FORM_URLENCODED_CONTENT_TYPE)){
                if(isValidParamForPost(request)){
                    chain.doFilter(request, response);
                    return;
                }else {
                    response.sendError(403,"發(fā)送的參數(shù)可能會引起sql注入,系統(tǒng)拒絕服務(wù)凡人!");
                    return;
                }
            }
            //處理application/json
            if(contentType.trim().toLowerCase().contains(HttpConst.JSON_CONTENT_TYPE)){
                HttpServletRequestBodyReaderWrapper wrapperRequest = new HttpServletRequestBodyReaderWrapper(request);
                String body = wrapperRequest.getBody();
                if(isValidParamForJsonPost(body)){
                    chain.doFilter(wrapperRequest, response);
                    return;
                }else {
                    response.sendError(403,"發(fā)送的參數(shù)可能會引起sql注入名党,系統(tǒng)拒絕服務(wù)!");
                    return;
                }
            }
        }
        chain.doFilter(request, response);
        return;

    }

    //sql注入效驗
    protected static boolean isSqlValidate(String str) {
        if(str==null||str.trim().isEmpty()){
            return true;
        }
        str = str.toLowerCase();//統(tǒng)一轉(zhuǎn)為小寫
        String[] badStrs = BAD_PARAM_STR.split("\\|");
        for (int i = 0; i < badStrs.length; i++) {
            if (Pattern.matches("^"+badStrs[i]+"$",str)) {
                return false;
            }
        }
        return true;
    }

    /**
     * get請求的參數(shù)是否無害   無害:true   有害:false
     * @param request
     * @return
     */
    public boolean isValidParamForGet(HttpServletRequest request){
        Enumeration params = request.getParameterNames();//獲得所有請求參數(shù)名
        System.out.println("SqlInjectFilter:發(fā)送的請求參數(shù)值串:"+params);
        while (params.hasMoreElements()) {
            String name = params.nextElement().toString(); //得到參數(shù)名
            String[] value = request.getParameterValues(name);//得到參數(shù)對應(yīng)值
            if(!isSqlValidate(name)){
                return false;
            }
            for (int i = 0; i < value.length; i++) {
                if(!isSqlValidate(value[i])){
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * post請求的參數(shù)是否無害   無害:true   有害:false
     * @param request
     * @return
     */
    public boolean isValidParamForPost(HttpServletRequest request){
        return isValidParamForGet(request);
    }

    /**
     * post請求的參數(shù)是否無害   無害:true   有害:false
     * @param body  請求體
     * @return
     */
    public boolean isValidParamForJsonPost(String body){
        System.out.println("SqlInjectFilter:發(fā)送的請求參數(shù)值串:"+body);
        if(body==null||body.trim().isEmpty()||body.trim().equalsIgnoreCase("{}")||!body.trim().contains(":")){
            return true;
        }
        Map<String,Object> map = JSON.parseObject(body,new TypeReference<Map<String,Object>>(){});
        if(map==null||map.size()==0){
            return true;
        }
        for (Map.Entry<String,Object> entry : map.entrySet()) {
            String key = entry.getKey();
            if(!isSqlValidate(key)){
                return false;
            }
            Object value = entry.getValue();
            String valueStr = String.valueOf(value);
            if(valueStr==null||valueStr.trim().isEmpty()||valueStr.trim().equalsIgnoreCase("null")){
                valueStr = null;
            }
            if(!isSqlValidate(valueStr)){
                return false;
            }
        }
        return true;
    }


    @Override
    public void destroy() {
    }

    @Override
    public void init(FilterConfig arg0) {
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末挠轴,一起剝皮案震驚了整個濱河市传睹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌岸晦,老刑警劉巖蒋歌,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異委煤,居然都是意外死亡堂油,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門碧绞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來府框,“玉大人,你說我怎么就攤上這事讥邻∑染福” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵兴使,是天一觀的道長系宜。 經(jīng)常有香客問我,道長发魄,這世上最難降的妖魔是什么盹牧? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任俩垃,我火速辦了婚禮,結(jié)果婚禮上汰寓,老公的妹妹穿的比我還像新娘口柳。我一直安慰自己,他們只是感情好有滑,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布跃闹。 她就那樣靜靜地躺著,像睡著了一般毛好。 火紅的嫁衣襯著肌膚如雪望艺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天肌访,我揣著相機與錄音找默,去河邊找鬼。 笑死场靴,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的港准。 我是一名探鬼主播旨剥,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼浅缸!你這毒婦竟也來了轨帜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤衩椒,失蹤者是張志新(化名)和其女友劉穎蚌父,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體毛萌,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡苟弛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了阁将。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片膏秫。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖做盅,靈堂內(nèi)的尸體忽然破棺而出缤削,到底是詐尸還是另有隱情,我是刑警寧澤吹榴,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布亭敢,位于F島的核電站,受9級特大地震影響图筹,放射性物質(zhì)發(fā)生泄漏帅刀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望劝篷。 院中可真熱鬧哨鸭,春花似錦、人聲如沸娇妓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哈恰。三九已至只估,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間着绷,已是汗流浹背蛔钙。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留荠医,地道東北人吁脱。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像彬向,于是被迫代替她去往敵國和親兼贡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容