wex5修复baas组件的sql注入问题及全局登录校验

147 阅读2分钟

wex5修复baas组件的sql注入问题及全局登录校验

原理:前端对body内容进行Aes加密,后端在过滤器中解密

前端

  1. 下载加密文件crypto-js,并放到\system\lib\base文件夹下

  2. 修改\system\common.min.js

    1. 约3131行引入crypto-js

image.png

2. 新增加密方法,并加密body的内容

image.png

后端

新建BodyRequestWrapper及ParamFilter类


import jx.sqlUtil.AESUtil;

import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;

public class ParamFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {

    }


    private static final HashMap<String, Integer> ignUriMap = new HashMap<>();

    // 忽略这些路径,不进行登录校验
    static {
        ignUriMap.put("/baas/jx/sqlUtil/sqlUtil/getNetWork", 1);
        ignUriMap.put("/baas/jx/sqlUtil/sqlUtil/getCustId", 1);
        ignUriMap.put("/baas/jx/sqlUtil/sqlUtil/getConfigParamList", 1);
        ignUriMap.put("/baas/jx/app/sumbitLogin", 1);
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) {
        HttpServletRequest request = (HttpServletRequest) req;

        String uri = request.getRequestURI();
//        System.out.println(uri);

        // 校验是否登录
        if (ignUriMap.get(uri) == null) {
            String baasSession = getBaasSession(request);
            if (baasSession == null) {
                outErrorMsg((HttpServletResponse) response);
                return;
            }
        }

        try {
            if (uri.contains("query")) {
                // 获取request的body参数,并做解密处理
                String postContent = getBody(request);
                if (postContent.contains("encryptBody|")) {
                    postContent = postContent.replace("encryptBody|", "").replace("\"", "");
                    postContent = AESUtil.decrypt(postContent);
                }
                // 将参数放入重写的方法中
                request = new BodyRequestWrapper(request, postContent);
            }
            chain.doFilter(request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void outErrorMsg(HttpServletResponse response) {
        HttpServletResponse httpResponse = response;
        httpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        // 设置响应内容类型
        httpResponse.setContentType("text/plain");
        // 获取PrintWriter来写入响应体
        try (PrintWriter out = httpResponse.getWriter()) {
            // 写入错误信息
            out.println("没有权限请登录后查询");
            // 刷新输出流,确保信息被发送
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static String getBaasSession(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        String baasSession = null;
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("baasSession")) {
                    baasSession = cookie.getValue();
                }
            }
        }
        return baasSession;
    }

    // 获取Request的body数据
    private String getBody(ServletRequest request) {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        InputStream inputStream = null;
        try {
            inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return stringBuilder.toString();
    }

    @Override
    public void destroy() {

    }
}
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

public class BodyRequestWrapper extends HttpServletRequestWrapper {

    // 存放JSON数据主体
    private final String body;

    public BodyRequestWrapper(HttpServletRequest request, String body) {
        super(request);
        this.body = body;
    }

    @Override
    public ServletInputStream getInputStream() {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
        return new ServletInputStream() {
            @Override
            public int read() {
                return byteArrayInputStream.read();
            }
        };
    }

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

修改配置文件

修改Web.xml,添加过滤器信息,注意修改包路径

<filter>
    <filter-name>paramfilter</filter-name>
    <filter-class>jx.ParamFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>paramfilter</filter-name>
    <url-pattern>/*</url-pattern></filter-mapping>