Commit 7d0e20be524a78861f9640eef45554bfb782774f

Authored by 芋道源码
Committed by Gitee
2 parents 3622b7f3 179fdc84

!383 优化 xss 的代码实现,独立 xss 包

Merge pull request !383 from 芋道源码/feature/dev-yunai
Showing 10 changed files with 83 additions and 76 deletions
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java
... ... @@ -2,27 +2,18 @@ package cn.iocoder.yudao.framework.web.config;
2 2  
3 3 import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService;
4 4 import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
5   -import cn.iocoder.yudao.framework.web.core.clean.JsoupXssCleaner;
6   -import cn.iocoder.yudao.framework.web.core.clean.XssCleaner;
7 5 import cn.iocoder.yudao.framework.web.core.filter.CacheRequestBodyFilter;
8 6 import cn.iocoder.yudao.framework.web.core.filter.DemoFilter;
9   -import cn.iocoder.yudao.framework.web.core.filter.XssFilter;
10 7 import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
11 8 import cn.iocoder.yudao.framework.web.core.handler.GlobalResponseBodyHandler;
12   -import cn.iocoder.yudao.framework.web.core.json.XssStringJsonDeserializer;
13 9 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
14   -import com.fasterxml.jackson.databind.ObjectMapper;
15 10 import org.springframework.beans.factory.annotation.Value;
16 11 import org.springframework.boot.autoconfigure.AutoConfiguration;
17   -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
18   -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
19 12 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
20   -import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
21 13 import org.springframework.boot.context.properties.EnableConfigurationProperties;
22 14 import org.springframework.boot.web.servlet.FilterRegistrationBean;
23 15 import org.springframework.context.annotation.Bean;
24 16 import org.springframework.util.AntPathMatcher;
25   -import org.springframework.util.PathMatcher;
26 17 import org.springframework.web.bind.annotation.RestController;
27 18 import org.springframework.web.cors.CorsConfiguration;
28 19 import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
... ... @@ -34,7 +25,7 @@ import javax.annotation.Resource;
34 25 import javax.servlet.Filter;
35 26  
36 27 @AutoConfiguration
37   -@EnableConfigurationProperties({WebProperties.class, XssProperties.class})
  28 +@EnableConfigurationProperties(WebProperties.class)
38 29 public class YudaoWebAutoConfiguration implements WebMvcConfigurer {
39 30  
40 31 @Resource
... ... @@ -108,15 +99,6 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer {
108 99 }
109 100  
110 101 /**
111   - * 创建 XssFilter Bean,解决 Xss 安全问题
112   - */
113   - @Bean
114   - @ConditionalOnBean(XssCleaner.class)
115   - public FilterRegistrationBean<XssFilter> xssFilter(XssProperties properties, PathMatcher pathMatcher, XssCleaner xssCleaner) {
116   - return createFilterBean(new XssFilter(properties, pathMatcher, xssCleaner), WebFilterOrderEnum.XSS_FILTER);
117   - }
118   -
119   - /**
120 102 * 创建 DemoFilter Bean,演示模式
121 103 */
122 104 @Bean
... ... @@ -125,33 +107,7 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer {
125 107 return createFilterBean(new DemoFilter(), WebFilterOrderEnum.DEMO_FILTER);
126 108 }
127 109  
128   -
129   - /**
130   - * Xss 清理者
131   - *
132   - * @return XssCleaner
133   - */
134   - @Bean
135   - @ConditionalOnMissingBean(XssCleaner.class)
136   - public XssCleaner xssCleaner() {
137   - return new JsoupXssCleaner();
138   - }
139   -
140   - /**
141   - * 注册 Jackson 的序列化器,用于处理 json 类型参数的 xss 过滤
142   - *
143   - * @return Jackson2ObjectMapperBuilderCustomizer
144   - */
145   - @Bean
146   - @ConditionalOnMissingBean(name = "xssJacksonCustomizer")
147   - @ConditionalOnBean(ObjectMapper.class)
148   - @ConditionalOnProperty(value = "yudao.xss.enable", havingValue = "true")
149   - public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssCleaner xssCleaner) {
150   - // 在反序列化时进行 xss 过滤,可以替换使用 XssStringJsonSerializer,在序列化时进行处理
151   - return builder -> builder.deserializerByType(String.class, new XssStringJsonDeserializer(xssCleaner));
152   - }
153   -
154   - private static <T extends Filter> FilterRegistrationBean<T> createFilterBean(T filter, Integer order) {
  110 + public static <T extends Filter> FilterRegistrationBean<T> createFilterBean(T filter, Integer order) {
155 111 FilterRegistrationBean<T> bean = new FilterRegistrationBean<>(filter);
156 112 bean.setOrder(order);
157 113 return bean;
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/XssProperties.java renamed to yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/xss/config/XssProperties.java
1   -package cn.iocoder.yudao.framework.web.config;
  1 +package cn.iocoder.yudao.framework.xss.config;
2 2  
3 3 import lombok.Data;
4 4 import org.springframework.boot.context.properties.ConfigurationProperties;
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/xss/config/YudaoXssAutoConfiguration.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.xss.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
  4 +import cn.iocoder.yudao.framework.xss.core.clean.JsoupXssCleaner;
  5 +import cn.iocoder.yudao.framework.xss.core.clean.XssCleaner;
  6 +import cn.iocoder.yudao.framework.xss.core.filter.XssFilter;
  7 +import cn.iocoder.yudao.framework.xss.core.json.XssStringJsonDeserializer;
  8 +import com.fasterxml.jackson.databind.ObjectMapper;
  9 +import org.springframework.boot.autoconfigure.AutoConfiguration;
  10 +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
  11 +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
  12 +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  13 +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
  14 +import org.springframework.boot.context.properties.EnableConfigurationProperties;
  15 +import org.springframework.boot.web.servlet.FilterRegistrationBean;
  16 +import org.springframework.context.annotation.Bean;
  17 +import org.springframework.util.PathMatcher;
  18 +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  19 +
  20 +import static cn.iocoder.yudao.framework.web.config.YudaoWebAutoConfiguration.createFilterBean;
  21 +
  22 +@AutoConfiguration
  23 +@EnableConfigurationProperties(XssProperties.class)
  24 +public class YudaoXssAutoConfiguration implements WebMvcConfigurer {
  25 +
  26 + /**
  27 + * Xss 清理者
  28 + *
  29 + * @return XssCleaner
  30 + */
  31 + @Bean
  32 + @ConditionalOnMissingBean(XssCleaner.class)
  33 + public XssCleaner xssCleaner() {
  34 + return new JsoupXssCleaner();
  35 + }
  36 +
  37 + /**
  38 + * 注册 Jackson 的序列化器,用于处理 json 类型参数的 xss 过滤
  39 + *
  40 + * @return Jackson2ObjectMapperBuilderCustomizer
  41 + */
  42 + @Bean
  43 + @ConditionalOnMissingBean(name = "xssJacksonCustomizer")
  44 + @ConditionalOnBean(ObjectMapper.class)
  45 + @ConditionalOnProperty(value = "yudao.xss.enable", havingValue = "true")
  46 + public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssCleaner xssCleaner) {
  47 + // 在反序列化时进行 xss 过滤,可以替换使用 XssStringJsonSerializer,在序列化时进行处理
  48 + return builder -> builder.deserializerByType(String.class, new XssStringJsonDeserializer(xssCleaner));
  49 + }
  50 +
  51 + /**
  52 + * 创建 XssFilter Bean,解决 Xss 安全问题
  53 + */
  54 + @Bean
  55 + @ConditionalOnBean(XssCleaner.class)
  56 + public FilterRegistrationBean<XssFilter> xssFilter(XssProperties properties, PathMatcher pathMatcher, XssCleaner xssCleaner) {
  57 + return createFilterBean(new XssFilter(properties, pathMatcher, xssCleaner), WebFilterOrderEnum.XSS_FILTER);
  58 + }
  59 +
  60 +}
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/clean/JsoupXssCleaner.java renamed to yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/xss/core/clean/JsoupXssCleaner.java
1   -package cn.iocoder.yudao.framework.web.core.clean;
  1 +package cn.iocoder.yudao.framework.xss.core.clean;
2 2  
3 3 import org.jsoup.Jsoup;
4 4 import org.jsoup.nodes.Document;
5 5 import org.jsoup.safety.Safelist;
6 6  
7 7 /**
8   - * jsonp 过滤字符串
  8 + * 基于 JSONP 实现 XSS 过滤字符串
9 9 */
10 10 public class JsoupXssCleaner implements XssCleaner {
11 11  
... ... @@ -24,21 +24,6 @@ public class JsoupXssCleaner implements XssCleaner {
24 24 this.baseUri = "";
25 25 }
26 26  
27   - public JsoupXssCleaner(Safelist safelist) {
28   - this.safelist = safelist;
29   - this.baseUri = "";
30   - }
31   -
32   - public JsoupXssCleaner(String baseUri) {
33   - this.safelist = buildSafelist();
34   - this.baseUri = baseUri;
35   - }
36   -
37   - public JsoupXssCleaner(Safelist safelist, String baseUri) {
38   - this.safelist = safelist;
39   - this.baseUri = baseUri;
40   - }
41   -
42 27 /**
43 28 * 构建一个 Xss 清理的 Safelist 规则。
44 29 * 基于 Safelist#relaxed() 的基础上:
... ... @@ -67,7 +52,6 @@ public class JsoupXssCleaner implements XssCleaner {
67 52 // 虽然可以重写 WhiteList#isSafeAttribute 来处理,但是有隐患,所以暂时不支持相对路径
68 53 // WHITELIST.removeProtocols("a", "href", "ftp", "http", "https", "mailto");
69 54 // WHITELIST.removeProtocols("img", "src", "http", "https");
70   -
71 55 return relaxedSafelist;
72 56 }
73 57  
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/clean/XssCleaner.java renamed to yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/xss/core/clean/XssCleaner.java
1   -package cn.iocoder.yudao.framework.web.core.clean;
  1 +package cn.iocoder.yudao.framework.xss.core.clean;
2 2  
3 3 /**
4 4 * 对 html 文本中的有 Xss 风险的数据进行清理
... ... @@ -12,4 +12,5 @@ public interface XssCleaner {
12 12 * @return 清理后的 html
13 13 */
14 14 String clean(String html);
  15 +
15 16 }
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/XssFilter.java renamed to yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/xss/core/filter/XssFilter.java
1   -package cn.iocoder.yudao.framework.web.core.filter;
  1 +package cn.iocoder.yudao.framework.xss.core.filter;
2 2  
3   -import cn.iocoder.yudao.framework.web.config.XssProperties;
4   -import cn.iocoder.yudao.framework.web.core.clean.XssCleaner;
  3 +import cn.iocoder.yudao.framework.xss.config.XssProperties;
  4 +import cn.iocoder.yudao.framework.xss.core.clean.XssCleaner;
5 5 import lombok.AllArgsConstructor;
6 6 import org.springframework.util.PathMatcher;
7 7 import org.springframework.web.filter.OncePerRequestFilter;
... ... @@ -14,8 +14,6 @@ import java.io.IOException;
14 14  
15 15 /**
16 16 * Xss 过滤器
17   - * <p>
18   - * 对 Xss 不了解的胖友,可以看看 http://www.iocoder.cn/Fight/The-new-girl-asked-me-why-AJAX-requests-are-not-secure-I-did-not-answer/
19 17 *
20 18 * @author 芋道源码
21 19 */
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/XssRequestWrapper.java renamed to yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/xss/core/filter/XssRequestWrapper.java
1   -package cn.iocoder.yudao.framework.web.core.filter;
  1 +package cn.iocoder.yudao.framework.xss.core.filter;
2 2  
3   -import cn.iocoder.yudao.framework.web.core.clean.XssCleaner;
  3 +import cn.iocoder.yudao.framework.xss.core.clean.XssCleaner;
4 4  
5 5 import javax.servlet.http.HttpServletRequest;
6 6 import javax.servlet.http.HttpServletRequestWrapper;
... ... @@ -13,6 +13,7 @@ import java.util.Map;
13 13 * @author 芋道源码
14 14 */
15 15 public class XssRequestWrapper extends HttpServletRequestWrapper {
  16 +
16 17 private final XssCleaner xssCleaner;
17 18  
18 19 public XssRequestWrapper(HttpServletRequest request, XssCleaner xssCleaner) {
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/json/XssStringJsonDeserializer.java renamed to yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/xss/core/json/XssStringJsonDeserializer.java
1   -package cn.iocoder.yudao.framework.web.core.json;
  1 +package cn.iocoder.yudao.framework.xss.core.json;
2 2  
3   -import cn.iocoder.yudao.framework.web.core.clean.XssCleaner;
  3 +import cn.iocoder.yudao.framework.xss.core.clean.XssCleaner;
4 4 import com.fasterxml.jackson.core.JsonParser;
5 5 import com.fasterxml.jackson.core.JsonToken;
6 6 import com.fasterxml.jackson.databind.DeserializationContext;
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/xss/package-info.java 0 → 100644
  1 +/**
  2 + * 针对 XSS 的基础封装
  3 + *
  4 + * XSS 说明:https://tech.meituan.com/2018/09/27/fe-security.html
  5 + */
  6 +package cn.iocoder.yudao.framework.xss;
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
1 1 cn.iocoder.yudao.framework.apilog.config.YudaoApiLogAutoConfiguration
2 2 cn.iocoder.yudao.framework.jackson.config.YudaoJacksonAutoConfiguration
3 3 cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration
4   -cn.iocoder.yudao.framework.web.config.YudaoWebAutoConfiguration
5 4 \ No newline at end of file
  5 +cn.iocoder.yudao.framework.web.config.YudaoWebAutoConfiguration
  6 +cn.iocoder.yudao.framework.xss.config.YudaoXssAutoConfiguration
... ...