zoukankan      html  css  js  c++  java
  • SpringBoot 解决跨站脚本漏洞(XSS)问题

    SpringBoot 解决跨站脚本漏洞(XSS)问题


    解决方案

    步骤如下:

    1、添加maven依赖

    pom.xml 文件中,增加如下依赖:

            <dependency>
                <groupId>org.apache.tomcat</groupId>
                <artifactId>tomcat-servlet-api</artifactId>
                <version>8.0.36</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
                <scope>provided</scope>
            </dependency>

    2、新增 XSSFilter.java

    在 config 目录下增加 XSSFilter.java,用于对请求接口进行过滤。代码如下:

    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import java.io.IOException;
    
    @WebFilter(filterName="XSSFilter", urlPatterns="/*")
    public class XSSFilter implements Filter {
    
        FilterConfig filterConfig = null;
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            this.filterConfig = filterConfig;
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            filterChain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) servletRequest), servletResponse);
        }
    
        @Override
        public void destroy() {
            this.filterConfig = null;
        }
    
    }

    3、新增 XssHttpServletRequestWrapper.java

    在config目录下,新增 XssHttpServletRequestWrapper.java,用于对请求参数进行预处理和解析。代码如下:

    import javax.servlet.ReadListener;
    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.Charset;
    import java.util.HashMap;
    import java.util.Map;
    
    public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
        public XssHttpServletRequestWrapper(HttpServletRequest request) {
            super(request);
        }
    
        @Override
        public String[] getParameterValues(String parameter) {
            String[] values = super.getParameterValues(parameter);
            if (values==null)  {
                return null;
            }
            int count = values.length;
            String[] encodedValues = new String[count];
            for (int i = 0; i < count; i++) {
                encodedValues[i] = cleanXSS(values[i]);
            }
            return encodedValues;
        }
    
        @Override
        public String getParameter(String parameter) {
            String value = super.getParameter(parameter);
            if (value != null) {
                return cleanXSS(value);
            }
            return null;
        }
    
        /**
         * 对 application/x-www-form-urlencoded 格式的POST请求参数,进行 cleanXSS解析
         * @return cleanXSS解析后的参数
         */
        @Override
        public Map<String, String[]> getParameterMap() {
            Map<String, String[]> values = super.getParameterMap();
            if (values == null) {
                return null;
            }
    
            Map<String, String[]> result = new HashMap<>();
            for (String key : values.keySet()) {
                String encodedKey = cleanXSS(key);
                int count = values.get(key).length;
                String[] encodedValues = new String[count];
                for (int i = 0; i < count; i++) {
                    encodedValues[i] = cleanXSS(values.get(key)[i]);
                }
                result.put(encodedKey, encodedValues);
            }
            return result;
        }
    
        @Override
        public String getHeader(String name) {
            String value = super.getHeader(name);
            if (value == null)
                return null;
            return cleanXSS(value);
        }
    
        private static String cleanXSS(String value) {
            value = value.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
            value = value.replaceAll("%3C", "&lt;").replaceAll("%3E", "&gt;");
            value = value.replaceAll("\\(", "&#40;").replaceAll("\\)", "&#41;");
            value = value.replaceAll("%28", "&#40;").replaceAll("%29", "&#41;");
            value = value.replaceAll("'", "&#39;");
            value = value.replaceAll("eval\\((.*)\\)", "");
            value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
            value = value.replaceAll("script", "");
            return value;
        }
    
        @Override
        public ServletInputStream getInputStream() throws IOException {
            final ByteArrayInputStream bais = new ByteArrayInputStream(inputHandlers(super.getInputStream ()).getBytes ());
    
            return new ServletInputStream() {
    
                @Override
                public int read() throws IOException {
                    return bais.read();
                }
    
                @Override
                public boolean isFinished() {
                    return false;
                }
    
                @Override
                public boolean isReady() {
                    return false;
                }
    
                @Override
                public void setReadListener(ReadListener readListener) { }
            };
        }
    
        public String inputHandlers(ServletInputStream servletInputStream){
            StringBuilder sb = new StringBuilder();
            BufferedReader reader = null;
            try {
                reader = new BufferedReader(new InputStreamReader(servletInputStream, Charset.forName("UTF-8")));
                String line = "";
                while ((line = reader.readLine()) != null) {
                    sb.append(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (servletInputStream != null) {
                    try {
                        servletInputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return  cleanXSS(sb.toString ());
        }
    
    }

    4、添加注解 @ServletComponentScan

    XXXApplication.java 的类名上方,用于扫描配置类。添加注解如下:

    @ServletComponentScan("com.XXX.config")

    示例如下:

  • 相关阅读:
    adb shell top
    数据清洗的方法
    Devices Tree加载流程
    Android驱动之设备树简介
    序列模式挖掘综述
    python 实现kmeans聚类
    numpy中sum(axis=0)和axis=1的计算原理
    win7 VMware下安装centos和Ubuntu共存
    python数据标准化
    python 用PIL Matplotlib处理图像的基本操作
  • 原文地址:https://www.cnblogs.com/miracle-luna/p/15754728.html
Copyright © 2011-2022 走看看