• SpringBoot防Xss攻击


    说明

    这几天自己学习了一下SpringBoot项目怎么预防Xss攻击,这里记录一下怎么防止Xss攻击的代码,等以后有需要用到的话,自己可以快速找到。

    依赖

    这里需要注意的是1.5到1.9版本有高危漏洞,需要升级到1.10.0以上版本,这是当前时间最新的版本。

    		<!--commons-text工具包,用于xss攻击对特殊参数字符做转换,1.51.9版本有高危漏洞-->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-text</artifactId>
                <version>1.10.0</version>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    项目文件结构

    处理非application/json提交方式使用下面二个类:
    XssFilter类,重写doFilter方法,然后调用XssHttpServletRequestWrapper类。
    XssHttpServletRequestWrapper类,只能对提交方式为x-www-form-urlencoded和form-data做特殊字符转换,不能对提交方式为application/json的数据格式做转换,如果没有指定提交方式,浏览器默认提交方式为x-www-form-urlencoded。
    处理application/json提交方式使用下面三个类:
    XssStringJsonDeSerializer类,这个类主要是对前端传递的数据格式为json格式的参数进行特殊字符转义。
    XssStringJsonSerializer类,这个类主要是处理后端向前端返回的json数据,将数据里面包含的特殊字符进行转义后发送。
    JacksonConfig类,调用上面2个自定义的序列化类,没有这个配置类,上面的2个类不会生效。
    在这里插入图片描述

    未处理Xss前的效果

    测试代码:
    在这里插入图片描述
    在谷歌浏览器直接输入接口请求测试如下:
    看到它这里是直接弹窗打印了,想要的返回值应该是浏览器页面中返回的是值才对。
    在这里插入图片描述

    处理非application/json提交方式的xss代码

    XssFilter类代码

    package com.hjl.mall.filter;
    
    import org.springframework.stereotype.Component;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import java.io.IOException;
    
    /**
     * XSS过滤器
     */
    @Component
    public class XssFilter implements Filter {
    	
    	@Override
        public void init(FilterConfig filterConfig) throws ServletException {
     
        }
    	
    	//重写doFilter方法
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            /**
             * 1. 重写getParamter方法
             * 2. 在getParamter中判断属性,然后对特殊字符进行编码,使用官方提供的工具类.
             * 3. 继续提交请求
             */
            chain.doFilter(new XssHttpServletRequestWrapper(
                    (HttpServletRequest) request), response);
        }
    
    	@Override
        public void destroy() {
     
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    XssHttpServletRequestWrapper类代码

    package com.hjl.mall.filter;
    
    import org.apache.commons.text.StringEscapeUtils;
    
    import javax.servlet.ServletInputStream;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import java.io.IOException;
    import java.util.Objects;
    
    /**
     * @ClassName XssHttpServletRequestWrapper
     * @Description 重写wrapper,只能对提交方式为x-www-form-urlencoded和form-data做特殊字符转换,不能对提交方式为json的数据格式做转换
     * @Version 1.0
     */
    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 ServletInputStream getInputStream() throws IOException {
            return super.getInputStream();
        }
    
        @Override
        public String[] getParameterValues(String name) {
            String[] parameterValues = super.getParameterValues(name);
            if (Objects.isNull(parameterValues)) {
                return null;
            }
            //对请求参数里面的特殊字符进行转义
            for (int i = 0; i < parameterValues.length; i++) {
                parameterValues[i] = StringEscapeUtils.escapeHtml4(parameterValues[i]);
            }
    
            return parameterValues;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    处理Xss后的效果

    可以看到达到了自己想要的结果,没有弹窗显示了,直接将结果正确显示到了页面中。
    在这里插入图片描述
    转义后的值如下:
    在这里插入图片描述
    但是这样对于json格式的数据起不到作用,如下图,发现并没有对里面的<、>、"这三个特殊符号进行转义:
    在这里插入图片描述

    处理application/json提交方式的xss代码

    XssStringJsonDeSerializer类代码

    package com.hjl.mall.filter;
    
    import java.io.IOException;
    
    import org.apache.commons.text.StringEscapeUtils;
    
    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.DeserializationContext;
    import com.fasterxml.jackson.databind.JsonDeserializer;
    
    /**
     * 对前端传递的数据格式为json格式的参数进行特殊字符转义
     */
    public class XssStringJsonDeSerializer extends JsonDeserializer<String> {
    
        @Override
        public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            //对json格式的参数值进行转义
            return StringEscapeUtils.escapeHtml4(jsonParser.getText());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    XssStringJsonSerializer类代码

    package com.hjl.mall.filter;
    
    import java.io.IOException;
    import java.util.Objects;
    
    import org.apache.commons.text.StringEscapeUtils;
    
    import com.fasterxml.jackson.core.JsonGenerator;
    import com.fasterxml.jackson.databind.JsonSerializer;
    import com.fasterxml.jackson.databind.SerializerProvider;
    
    /**
     * 处理后端向前端返回的json数据,将数据进行转义后发送
     */
    public class XssStringJsonSerializer extends JsonSerializer<String> {
    
        @Override
        public Class<String> handledType() {
            return String.class;
        }
    
        @Override
        public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            if (Objects.nonNull(value)) {
                //将json格式数据转义后发送给前端
                String encodedValue = StringEscapeUtils.escapeHtml4(value);
                jsonGenerator.writeString(encodedValue);
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    JacksonConfig类代码

    package com.hjl.mall.config;
    
    import com.hjl.mall.filter.XssStringJsonDeSerializer;
    import com.hjl.mall.filter.XssStringJsonSerializer;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.module.SimpleModule;
    
    /**
     * 对json格式数据做序列化和反序列化操作,防止xss攻击
     * XssFilter类
     * XssHttpServletRequestWrapper类
     * XssStringJsonDeSerializer类
     * XssStringJsonSerializer类
     * JacksonConfig类
     * 这5个类是一起的,都是用来防止xss攻击,前2个类是用来处理提交方式为x-www-form-urlencoded和form-data做特殊字符转换
     * 后面三类是对application/json提交方式做处理
     */
    @Configuration
    public class JacksonConfig implements WebMvcConfigurer{
    
        @Bean
        public ObjectMapper xssObjectMapper(Jackson2ObjectMapperBuilder builder) {
            ObjectMapper objectMapper = builder.createXmlMapper(false).build();
            //注入自定义的序列化工具,将@RequestBody的json格式参数做转义处理
            SimpleModule simpleModule = new SimpleModule(XssStringJsonSerializer.class.getSimpleName());
            //只对入参json进行特殊字符转义
            simpleModule.addDeserializer(String.class, new XssStringJsonDeSerializer());
            //对返回给前端的json数据(特殊字符)进行转义,这里暂时注释掉,当前项目暂不需要对返回给前端的数据进行转义
            //simpleModule.addSerializer(String.class, new XssStringJsonSerializer());
            objectMapper.registerModule(simpleModule);
            return objectMapper;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    json格式处理Xss后的效果

    测试代码:
    在这里插入图片描述
    因为是post请求,所以这里使用postman工具对接口进行测试:
    发现已经转义成功。
    在这里插入图片描述

    注意事项(补充说明)

    这个JacksonConfig类 里面的代码,我注释掉了对返回json数据格式做转义的处理。
    在这里插入图片描述
    不注释掉的话,会进行2次转义处理,效果如下:
    它这里先是对入参<转义为<,然后又将<里面的&符合在返回给前端的时候又进行了一次转义,所以变成了&lt;
    在这里插入图片描述
    这一种会出现这一种情况,我这里用txt简单写一个html页面代码:
    在这里插入图片描述
    然后我将txt后缀改为html,效果如下:
    在这里插入图片描述
    所以这里JacksonConfig类里面的XssStringJsonSerializer类调用需要根据自己的项目实际情况需要是否引用。
    在这里插入图片描述
    好了,笔记先做到这里,等以后自己有需要直接引用即可。

  • 相关阅读:
    SSRF-服务器端请求伪造-相关知识
    cmake应用:集成gtest进行单元测试
    GO学习之切片操作
    基于JAVA基于MVC框架的在线书店设计计算机毕业设计源码+系统+mysql数据库+lw文档+部署
    【若依】前后端分离版本部署到Tomcat完整过程
    基于nodejs+express+knex+mysql搭建一个后台服务
    Spark的内存管理
    AQS面试题
    java计算机毕业设计教师招聘考试题库系统源码+mysql数据库+系统+lw文档+部署
    Linux网络编程-网络层IP协议
  • 原文地址:https://blog.csdn.net/weixin_48040732/article/details/127799769