SpringBoot中Post请求参数过滤SQL防止注入

SpringBoot中Post请求参数过滤SQL防止注入

BodyReaderRequestWrapper 代码:

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;

public class BodyReaderRequestWrapper extends HttpServletRequestWrapper {

    private final String body;

    public String getBody() {
        return body;
    }

    /**
     * 取出请求体body中的参数(创建对象时执行)
     * @param request
     */
    public BodyReaderRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        StringBuilder sb = new StringBuilder();
        InputStream ins = request.getInputStream();
        BufferedReader isr = null;
        try{
            if (ins != null) {
                isr = new BufferedReader(new InputStreamReader(ins));
                char[] charBuffer = new char[128];
                int readCount;
                while ((readCount = isr.read(charBuffer)) != -1) {
                    sb.append(charBuffer, 0, readCount);
                }
            }
        } finally {
            if(isr != null) {
                isr.close();
            }
        }

        sb.toString();
        body = sb.toString();
    }

    @Override
    public BufferedReader getReader() {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() {
        final ByteArrayInputStream byteArrayIns = new ByteArrayInputStream(body.getBytes());
        return new ServletInputStream() {

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }

            @Override
            public int read() {
                return byteArrayIns.read();
            }

        };
    }
}

SqlFilter 代码:

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;
import java.util.Set;

@WebFilter(urlPatterns = "/*")
public class SqlFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String contentType = request.getContentType();
        BodyReaderRequestWrapper wrapper = null;
        if ("application/json".equals(contentType)) {
            wrapper = new BodyReaderRequestWrapper(request);
            String requestPostStr = wrapper.getBody();
            if (requestPostStr.startsWith("{")) {
                //解析json对象
                boolean b = resolveJSONObjectObj(requestPostStr);
                if (!b) return;
            } else if (requestPostStr.startsWith("[")) {
                //把数据转换成json数组
                JSONArray jsonArray = JSONArray.parseArray(requestPostStr);
                jsonArray.forEach(json -> {
                    //解析json对象
                    boolean b = resolveJSONObjectObj(json.toString());
                    if (!b) return;
                });
            }
        } else {
            //application/x-www-form-urlencoded
            Map<String, String[]> parameterMap = request.getParameterMap();
            for (Map.Entry<String,String[]> entry : parameterMap.entrySet()) {
                //校验参数值是否合法
                String[] value = entry.getValue();
                for (String s : value) {
                    //校验参数值是否合法
                    boolean b = verifySql(s);
                    if (!b) {
                        return;
                    }
                }
            }
        }
        if (wrapper == null) {
            filterChain.doFilter(servletRequest,servletResponse);
        } else {
            filterChain.doFilter(wrapper,servletResponse);
        }
    }

    /**
     * 对JSONObject对象进行递归参数解析
     * @param requestPostStr
     * @return
     */
    private boolean resolveJSONObjectObj(String requestPostStr) {
        boolean isover = true;
        // 创建需要处理的json对象
        JSONObject jsonObject = JSONObject.parseObject(requestPostStr);
        // 获取所有的参数key
        Set<String> keys = jsonObject.keySet();
        if (keys.size() > 0) {
            for (String key : keys) {
                //获取参数名称
                String value;
                if (jsonObject.get(key) != null) {
                    value = String.valueOf(jsonObject.get(key));
                    //当value为数组时
                    if(value.startsWith("[")){
                        //把数据转换成json数组
                        JSONArray jsonArray = JSONArray.parseArray(value);
                        for (Object o : jsonArray) {
                            //解析json对象
                            boolean b = resolveJSONObjectObj(o.toString());
                            if (!b) {
                                isover = false;
                                break;
                            }
                        }
                    } else if (value.startsWith("{")) {
                        boolean b = resolveJSONObjectObj(value);
                        if (!b) {
                            isover = false;
                            break;
                        }
                    } else {
                        //校验参数值是否合法
                        boolean b = verifySql(value);
                        if (!b) {
                            isover = false;
                            break;
                        }
                    }
                }
            }
        }
        return isover;
    }

    @Override
    public void destroy() {

    }

    /**
     * 校验参数非法字符
     */
    public boolean verifySql(String parameter) {
        if (
                    parameter.toLowerCase().contains("select")
                    || parameter.toLowerCase().contains("update")
                    || parameter.toLowerCase().contains("delete")
                    || parameter.toLowerCase().contains("insert")
                    || parameter.toLowerCase().contains("truncate")
                    || parameter.toLowerCase().contains("substr")
                    || parameter.toLowerCase().contains("char")
                    || parameter.toLowerCase().contains("exec")
                    || parameter.toLowerCase().contains("master")
                    || parameter.toLowerCase().contains("drop")
                    || parameter.toLowerCase().contains("execute")
                    || parameter.toLowerCase().contains("xp_cmdshell")
                    || parameter.toLowerCase().contains("use")
                    || parameter.toLowerCase().contains("column_name")
                    || parameter.toLowerCase().contains("information_schema.columns")
                    || parameter.toLowerCase().contains("table_schema")
                    || parameter.toLowerCase().contains("union")
            ) {
                return false;
            } else {
                return true;
            }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值