springboot defense is cross-site scripting (XSS) attack

Protection against cross-site scripting (XSS) attacks

XSS attacks usually refer to injecting malicious instructions into webpages by exploiting the loopholes in the website system storage system, and malicious scripts will be automatically executed when users load the webpage.

for example:

<script>
    alert(xss);
</script>

If the client can execute javascript in your browser, then the cookie or token can be stolen.

1. pom.xml add dependencies

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.14</version>
        </dependency>

You can view the knowledge points of hutool

HTML Tool Class-HtmlUtil Hutool Reference Documentation

 

 

2. Create a new class XssHttpServletRequestWrapper in your own com.xxx.filter.xss package

package com.xxxx.filter.xss;


public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
    /**
     * 声明子类的构造器
     * @param request
     */
    public XssHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getParameter(String name) {
        String value = super.getParameter(name);
        if(!StrUtil.hasEmpty(value)) {
            //把一些带script标签的 过滤掉,变成普通文本 HtmlUtil.filter 过滤HTML文本,防止XSS攻击
            value = HtmlUtil.filter(value);
        }
        //然后可以安全的保存到数据库里面的
        return value;
    }

    /**
     * 把返回的参数也进行转义
     * @param name
     * @return
     */
    @Override
    public String[] getParameterValues(String name) {
        String[] values = super.getParameterValues(name);
        if(values != null){
            for (int i = 0;i < values.length; i++){
                String value = values[i];
                if(!StrUtil.hasEmpty(value)){
                    //把一些带script标签的 过滤掉,变成普通文本 HtmlUtil.filter 过滤HTML文本,防止XSS攻击
                    value = HtmlUtil.filter(value);
                }
                values[i] = value;
            }
        }
        //然后可以安全的保存到数据库里面的
        return values;
    }

    /**
     * 把请求中的数据返回一个map对象,也要做一下转义
     * @return
     */
    @Override
    public Map<String, String[]> getParameterMap() {
        Map<String, String[]> parameters = super.getParameterMap();
        LinkedHashMap<String, String[]> map = new LinkedHashMap();
        if(parameters!=null){
            for (String key:parameters.keySet()){
                String[] values=parameters.get(key);
                for (int i = 0; i < values.length; i++) {
                    String value = values[i];
                    if (!StrUtil.hasEmpty(value)) {
                        //HtmlUtil.filter 过滤HTML文本,防止XSS攻击
                        value = HtmlUtil.filter(value);
                    }
                    values[i] = value;
                }
                map.put(key,values);
            }
        }
        return map;
    }

    /**
     * 从请求头获取到数据 也要做一下转义
     * @param name
     * @return
     */
    @Override
    public String getHeader(String name) {
        String value= super.getHeader(name);
        if (!StrUtil.hasEmpty(value)) {
            //HtmlUtil.filter 过滤HTML文本,防止XSS攻击
            value = HtmlUtil.filter(value);
        }
        return value;
    }

    /**
     * 通过io流 读取数据 也要做一下转义
     * @return
     * @throws IOException
     */
    @Override
    public ServletInputStream getInputStream() throws IOException {
        InputStream in= super.getInputStream();
        InputStreamReader reader=new InputStreamReader(in, Charset.forName("UTF-8"));
        BufferedReader buffer=new BufferedReader(reader);
        StringBuffer body=new StringBuffer();
        String line=buffer.readLine();
        while(line!=null){
            body.append(line);
            line=buffer.readLine();
        }
        buffer.close();
        reader.close();
        in.close();
        Map<String,Object> map=JSONUtil.parseObj(body.toString());
        Map<String,Object> result=new LinkedHashMap<>();
        for(String key:map.keySet()){
            Object val=map.get(key);
            if(val instanceof String){
                if(!StrUtil.hasEmpty(val.toString())){
                    //转义
                    result.put(key,HtmlUtil.filter(val.toString()));
                }
            }
            else {
                //不需要转义的数据
                result.put(key,val);
            }
        }
        //又转成json的字符串
        String json=JSONUtil.toJsonStr(result);
        ByteArrayInputStream bain=new ByteArrayInputStream(json.getBytes());
        return new ServletInputStream() {
            @Override
            public int read() throws IOException {
                return bain.read();
            }

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

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

            @Override
            public void setReadListener(ReadListener readListener) {

            }
        };
    }
}

 3. Build another XssFilter

package com.xxxx.filter.xss;

/**
 * urlPatterns = "/*"表示所有请求路由都需要拦截的
 */
@WebFilter(urlPatterns = "/*")
public class XssFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        XssHttpServletRequestWrapper wrapper = new XssHttpServletRequestWrapper(request);
        //通过后 继续往下执行 放行
        filterChain.doFilter(wrapper,servletResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

4. The last step is to add to the startup file

@ServletComponentScan

  

5. start

6. Finally, the backend will filter out the <script> tag.

The result is

alert(xxxxx);

7. However, the html tags are also filtered out at the same time. I don't want to filter out the html tags.

Unfinished follow-up....

Guess you like

Origin blog.csdn.net/deng_zhihao692817/article/details/130615017