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() {
    
        }
    }
  • 相关阅读:
    汉英单词对照,汉英部分
    解密SQL Server存储过程等对象
    统计信息对执行计划的影响(二)
    统计信息对执行计划的影响(一)
    asp.net 避免 ajax 定时调用,利用 ashx 实现 long polling (长轮询)
    [ADO.NET][Command]如何抓取第一筆資料的第一個欄位或scalar值?
    鱼骨图
    js 中跳出多层循环
    IIS无法 添加/编辑 应用程序扩展名映射的原因
    如何让域名后面不显示xxx.do后缀
  • 原文地址:https://www.cnblogs.com/jentary/p/11164940.html
Copyright © 2011-2022 走看看