zoukankan      html  css  js  c++  java
  • xss--知识点

    如何在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来自:

        compile("org.apache.commons:commons-text:1.6")

    第三步:自定义过滤器

    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() {
    
        }
    }
  • 相关阅读:
    wex5 实战 框架拓展之2 事件派发与data刷新
    wex5 实战 框架拓展之1 公共data组件(Data)
    wex5 实战 HeidiSQL 导入Excel数据
    wex5 实战 手指触屏插件 hammer的集成与优劣
    wex5 实战 登陆帐号更换与用户id一致性
    wex5 实战 用户点评与提交设计技巧
    wex5 实战 省市县三级联动与地址薄同步
    wex5 实战 wex5与js的组件关系与执行顺序(父子与先后)
    wex5 实战 单页模式下的多页面数据同步
    [BZOJ]4237: 稻草人
  • 原文地址:https://www.cnblogs.com/jentary/p/11164940.html
Copyright © 2011-2022 走看看