zoukankan      html  css  js  c++  java
  • springboot项目中进行XSS过滤

    简单介绍

    XSS : 跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意攻击用户的特殊目的。
    过滤方式:主要通过对html标签进行转义的方式达到过滤的目的

    话不多说,直接上代码

    实现方式,共分为三步:

    第一步:在springboot启动类上添加@ServletComponentScan注解,该注解会自动扫描到我们自定义的filter(还有其他方式,这里就不赘述了,大家有兴趣的可以自行百度)

    第二步:定义request的包装类,重写其中的关键方法

    import com.alibaba.fastjson.JSON;
    import org.apache.commons.text.StringEscapeUtils;
    import javax.servlet.ReadListener;
    import javax.servlet.ServletInputStream;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import java.io.*;
    import java.nio.charset.Charset;
    import java.util.HashMap;
    import java.util.Map;
    /**
     * ServletRequest包装类,对request做XSS过滤处理
     * @author Jozz
     */
    public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
        public XssHttpServletRequestWrapper(HttpServletRequest request) {
            super(request);
        }
        @Override
        public String getHeader(String name) {
            return StringEscapeUtils.escapeHtml4(super.getHeader(name));
        }
        @Override
        public String getQueryString() {
            return StringEscapeUtils.escapeHtml4(super.getQueryString());
        }
        @Override
        public String getParameter(String name) {
            return StringEscapeUtils.escapeHtml4(super.getParameter(name));
        }
        @Override
        public String[] getParameterValues(String name) {
            String[] values = super.getParameterValues(name);
            if(values != null) {
                int length = values.length;
                String[] escapseValues = new String[length];
                for(int i = 0; i < length; i++){
                    escapseValues[i] = StringEscapeUtils.escapeHtml4(values[i]);
                }
                return escapseValues;
            }
            return values;
        }
        @Override
        public ServletInputStream getInputStream() throws IOException {
            String str=getRequestBody(super.getInputStream());
            Map<String,Object> map= JSON.parseObject(str,Map.class);
            Map<String,Object> resultMap=new HashMap<>(map.size());
            for(String key:map.keySet()){
                Object val=map.get(key);
                if(map.get(key) instanceof String){
                    resultMap.put(key,StringEscapeUtils.escapeHtml4(val.toString()));
                }else{
                    resultMap.put(key,val);
                }
            }
            str=JSON.toJSONString(resultMap);
            final ByteArrayInputStream bais = new ByteArrayInputStream(str.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 listener) {
                }
            };
        }
        private String getRequestBody(InputStream stream) {
            String line = "";
            StringBuilder body = new StringBuilder();
            int counter = 0;
            // 读取POST提交的数据内容
            BufferedReader reader = new BufferedReader(new InputStreamReader(stream, Charset.forName("UTF-8")));
            try {
                while ((line = reader.readLine()) != null) {
                    body.append(line);
                    counter++;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return body.toString();
        }
    }

    其中的StringEscapeUtils来自:

    对于不可信的输入可以采用 apache.commons.lang3.StringEscapeUtils 对输入字符串进行过滤,将’<’ ‘>’ ‘*’ 三个字符转换成html编码格式 < & &gt. 防止而已的HTML注入攻击

    第三步:自定义过滤器:

    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import java.io.IOException;
    /**
     * XSS过滤器
     * @author Jozz
     */
    @WebFilter(filterName="xssFilter",urlPatterns="/*")
    public class XssFilter implements Filter {
        @Override
        public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {
        }
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest)servletRequest;
            String path = request.getServletPath();
            //由于我的@WebFilter注解配置的是urlPatterns="/*"(过滤所有请求),所以这里对不需要过滤的静态资源url,作忽略处理(大家可以依照具体需求配置)
            String[] exclusionsUrls = {".js",".gif",".jpg",".png",".css",".ico"};
            for (String str : exclusionsUrls) {
                if (path.contains(str)) {
                    filterChain.doFilter(servletRequest,servletResponse);
                    return;
                }
            }
            filterChain.doFilter(new XssHttpServletRequestWrapper(request),servletResponse);
        }
        @Override
        public void destroy() {
        }
    }

    到这里就大功告成了~若您觉得文章有用,欢迎点赞分享!

  • 相关阅读:
    获取Spring项目配置文件元素
    MyEclipse安装插件的几种方法
    排序-->桶排序
    排序-->冒泡排序
    排序-->选择排序
    排序-->插入排序
    约瑟夫问题----(数组+list)实现
    约瑟夫问题--->环形链表
    py---pycharm快捷键
    双向链表--简单的增删改查
  • 原文地址:https://www.cnblogs.com/deityjian/p/12518146.html
Copyright © 2011-2022 走看看