美文网首页Java 杂谈计算机杂谈
2019-08-23/防sql注入过滤器

2019-08-23/防sql注入过滤器

作者: 呼噜噜睡 | 来源:发表于2019-08-23 22:32 被阅读2次

现在后端的框架也做了防止sql注入的手段,比如使用PreparedStatement+占位符。但加一层过滤器总归更加安全一点。这里的防sql注入的过滤器可以对普通get/post请求进行参数过滤,也可以对post+application/json等请求进行参数过滤。
该过滤器使用了请求的包装类,具体参考我的上一篇文章https://www.jianshu.com/p/579558b6dc63
,这里只给出过滤参数的部分:

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转义之后的字符会被该过滤器当作sql注入
 * @author
 * @time 20190425
 */
public class SqlInjectFilter implements Filter {

    /**
     * 需要过滤的sql关键字,可以手动添加
     */
    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,"发送的参数可能会引起sql注入,系统拒绝服务!");
                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,"发送的参数可能会引起sql注入,系统拒绝服务!");
                    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,"发送的参数可能会引起sql注入,系统拒绝服务!");
                    return;
                }
            }
        }
        chain.doFilter(request, response);
        return;

    }

    //sql注入效验
    protected static boolean isSqlValidate(String str) {
        if(str==null||str.trim().isEmpty()){
            return true;
        }
        str = str.toLowerCase();//统一转为小写
        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请求的参数是否无害   无害:true   有害:false
     * @param request
     * @return
     */
    public boolean isValidParamForGet(HttpServletRequest request){
        Enumeration params = request.getParameterNames();//获得所有请求参数名
        System.out.println("SqlInjectFilter:发送的请求参数值串:"+params);
        while (params.hasMoreElements()) {
            String name = params.nextElement().toString(); //得到参数名
            String[] value = request.getParameterValues(name);//得到参数对应值
            if(!isSqlValidate(name)){
                return false;
            }
            for (int i = 0; i < value.length; i++) {
                if(!isSqlValidate(value[i])){
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * post请求的参数是否无害   无害:true   有害:false
     * @param request
     * @return
     */
    public boolean isValidParamForPost(HttpServletRequest request){
        return isValidParamForGet(request);
    }

    /**
     * post请求的参数是否无害   无害:true   有害:false
     * @param body  请求体
     * @return
     */
    public boolean isValidParamForJsonPost(String body){
        System.out.println("SqlInjectFilter:发送的请求参数值串:"+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) {
    }
}

相关文章

  • 2019-08-23/防sql注入过滤器

    现在后端的框架也做了防止sql注入的手段,比如使用PreparedStatement+占位符。但加一层过滤器总归更...

  • 2019-08-22/XSS过滤器

    做后端的同学都知道,XSS过滤器,防sql注入过滤器等是常用的 。关于什么是XSS攻击,网上的说法很多,自己百度一...

  • 6.mysql安全性

    SQL语句应该考虑哪些安全性? Sql查询的安全方案【就是考察sql注入】 1.使用预处理语句,防Sql注入 【p...

  • 防sql注入

    1.对提交的转义 //如果启用了魔术引号 echo$_POST['lastname'];//O\'reilly e...

  • SQL防注入

    1、什么是SQL注入 具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以...

  • 网络信息安全攻防学习平台 注入关第三

    防注入分值: 300 小明终于知道,原来黑客如此的吊,还有sql注入这种高端技术,因此他开始学习防注入! 通关地址...

  • 面试题1--web安全问题,死锁,进程与线程,并发与并行

    web安全问题:SQL防注入,XSS攻击,CSRF攻击 1. SQL注入是一种将sql代码添加到输入参数中,传递到...

  • 基于springboot的sql防注入过滤器

    何为SQL注入SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中...

  • 学习笔记 face

    1.使用预处理语句防 sql注入 sql注入 id = "1 or 1=1"; 2.写入数据库的数据要进行特殊字符...

  • SQL防注入总结

    0x00 背景 自己一个人学了这么久的web安全,感觉需要一些总结,加上今天下午电话面试总被问到的问题,自己总结了...

网友评论

    本文标题:2019-08-23/防sql注入过滤器

    本文链接:https://www.haomeiwen.com/subject/hrpxectx.html