Commit 099754c26e9f1e0e460ddefd25609a73625d157f

Authored by gaibu
1 parent d7bec143

fix: xss 启用后编辑器上传图片错误

yudao-dependencies/pom.xml
... ... @@ -396,11 +396,6 @@
396 396  
397 397 <!-- 工具类相关 -->
398 398 <dependency>
399   - <groupId>org.jsoup</groupId>
400   - <artifactId>jsoup</artifactId>
401   - <version>${jsoup.version}</version>
402   - </dependency>
403   - <dependency>
404 399 <groupId>cn.iocoder.boot</groupId>
405 400 <artifactId>yudao-common</artifactId>
406 401 <version>${revision}</version>
... ... @@ -528,6 +523,12 @@
528 523 <version>${ip2region.version}</version>
529 524 </dependency>
530 525  
  526 + <dependency>
  527 + <groupId>org.jsoup</groupId>
  528 + <artifactId>jsoup</artifactId>
  529 + <version>${jsoup.version}</version>
  530 + </dependency>
  531 +
531 532 <!-- 三方云服务相关 -->
532 533 <dependency>
533 534 <groupId>com.squareup.okio</groupId>
... ...
yudao-framework/yudao-common/pom.xml
... ... @@ -133,10 +133,6 @@
133 133 <artifactId>transmittable-thread-local</artifactId>
134 134 </dependency>
135 135  
136   - <dependency>
137   - <groupId>org.jsoup</groupId>
138   - <artifactId>jsoup</artifactId>
139   - </dependency>
140 136 </dependencies>
141 137  
142 138 </project>
... ...
yudao-framework/yudao-spring-boot-starter-web/pom.xml
... ... @@ -67,6 +67,11 @@
67 67 <scope>provided</scope> <!-- 设置为 provided,主要是 GlobalExceptionHandler 使用 -->
68 68 </dependency>
69 69  
  70 + <!-- xss -->
  71 + <dependency>
  72 + <groupId>org.jsoup</groupId>
  73 + <artifactId>jsoup</artifactId>
  74 + </dependency>
70 75 </dependencies>
71 76  
72 77 </project>
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java
... ... @@ -131,8 +131,8 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer {
131 131 *
132 132 * @return XssCleaner
133 133 */
134   - @ConditionalOnMissingBean(XssCleaner.class)
135 134 @Bean
  135 + @ConditionalOnMissingBean(XssCleaner.class)
136 136 public XssCleaner xssCleaner() {
137 137 return new JsoupXssCleaner();
138 138 }
... ... @@ -145,12 +145,12 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer {
145 145 @Bean
146 146 @ConditionalOnMissingBean(name = "xssJacksonCustomizer")
147 147 @ConditionalOnBean(ObjectMapper.class)
148   - public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssCleaner xssCleaner, XssProperties xssProperties) {
  148 + @ConditionalOnProperty(value = "yudao.xss.enable", havingValue = "true")
  149 + public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssCleaner xssCleaner) {
149 150 // 在反序列化时进行 xss 过滤,可以替换使用 XssStringJsonSerializer,在序列化时进行处理
150   - return builder -> builder.deserializerByType(String.class, new XssStringJsonDeserializer(xssCleaner, xssProperties));
  151 + return builder -> builder.deserializerByType(String.class, new XssStringJsonDeserializer(xssCleaner));
151 152 }
152 153  
153   -
154 154 private static <T extends Filter> FilterRegistrationBean<T> createFilterBean(T filter, Integer order) {
155 155 FilterRegistrationBean<T> bean = new FilterRegistrationBean<>(filter);
156 156 bean.setOrder(order);
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/clean/JsoupXssCleaner.java
... ... @@ -4,6 +4,9 @@ import org.jsoup.Jsoup;
4 4 import org.jsoup.nodes.Document;
5 5 import org.jsoup.safety.Safelist;
6 6  
  7 +/**
  8 + * jsonp 过滤字符串
  9 + */
7 10 public class JsoupXssCleaner implements XssCleaner {
8 11  
9 12 private final Safelist safelist;
... ... @@ -37,19 +40,15 @@ public class JsoupXssCleaner implements XssCleaner {
37 40 }
38 41  
39 42 /**
40   - * <p>
41 43 * 构建一个 Xss 清理的 Safelist 规则。
42   - * </p>
43   - *
44   - * <ul>
45 44 * 基于 Safelist#relaxed() 的基础上:
46   - * <li>扩展支持了 style 和 class 属性</li>
47   - * <li>a 标签额外支持了 target 属性</li>
48   - * <li>img 标签额外支持了 data 协议,便于支持 base64</li>
49   - * </ul>
  45 + * 1. 扩展支持了 style 和 class 属性
  46 + * 2. a 标签额外支持了 target 属性
  47 + * 3. img 标签额外支持了 data 协议,便于支持 base64
  48 + *
50 49 * @return Safelist
51 50 */
52   - protected Safelist buildSafelist() {
  51 + private Safelist buildSafelist() {
53 52 // 使用 jsoup 提供的默认的
54 53 Safelist relaxedSafelist = Safelist.relaxed();
55 54 // 富文本编辑时一些样式是使用 style 来进行实现的
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/clean/XssCleaner.java
... ... @@ -4,6 +4,7 @@ package cn.iocoder.yudao.framework.web.core.clean;
4 4 * 对 html 文本中的有 Xss 风险的数据进行清理
5 5 */
6 6 public interface XssCleaner {
  7 +
7 8 /**
8 9 * 清理有 Xss 风险的文本
9 10 *
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/XssRequestWrapper.java
... ... @@ -20,6 +20,7 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
20 20 this.xssCleaner = xssCleaner;
21 21 }
22 22  
  23 + // ============================ parameter ============================
23 24 @Override
24 25 public Map<String, String[]> getParameterMap() {
25 26 Map<String, String[]> map = new LinkedHashMap<>();
... ... @@ -57,6 +58,7 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
57 58 return xssCleaner.clean(value);
58 59 }
59 60  
  61 + // ============================ attribute ============================
60 62 @Override
61 63 public Object getAttribute(String name) {
62 64 Object value = super.getAttribute(name);
... ... @@ -66,6 +68,7 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
66 68 return value;
67 69 }
68 70  
  71 + // ============================ header ============================
69 72 @Override
70 73 public String getHeader(String name) {
71 74 String value = super.getHeader(name);
... ... @@ -75,6 +78,7 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
75 78 return xssCleaner.clean(value);
76 79 }
77 80  
  81 + // ============================ queryString ============================
78 82 @Override
79 83 public String getQueryString() {
80 84 String value = super.getQueryString();
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/json/XssStringJsonDeserializer.java
1 1 package cn.iocoder.yudao.framework.web.core.json;
2 2  
3   -import cn.iocoder.yudao.framework.web.config.XssProperties;
4 3 import cn.iocoder.yudao.framework.web.core.clean.XssCleaner;
5 4 import com.fasterxml.jackson.core.JsonParser;
6 5 import com.fasterxml.jackson.core.JsonToken;
... ... @@ -12,21 +11,21 @@ import lombok.extern.slf4j.Slf4j;
12 11 import java.io.IOException;
13 12  
14 13 /**
15   - * XSS过滤 jackson 反序列化器
  14 + * XSS 过滤 jackson 反序列化器。
  15 + * 在反序列化的过程中,会对字符串进行 XSS 过滤。
16 16 *
17   - * 参考 ballcat 实现
  17 + * @author Hccake
18 18 */
19 19 @Slf4j
20 20 @AllArgsConstructor
21 21 public class XssStringJsonDeserializer extends StringDeserializer {
22 22  
23 23 private final XssCleaner xssCleaner;
24   - private final XssProperties xssProperties;
25 24  
26 25 @Override
27 26 public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
28 27 if (p.hasToken(JsonToken.VALUE_STRING)) {
29   - return getCleanText(p.getText());
  28 + return xssCleaner.clean(p.getText());
30 29 }
31 30 JsonToken t = p.currentToken();
32 31 // [databind#381]
... ... @@ -49,22 +48,12 @@ public class XssStringJsonDeserializer extends StringDeserializer {
49 48 if (t == JsonToken.START_OBJECT) {
50 49 return ctxt.extractScalarFromObject(p, this, _valueClass);
51 50 }
52   - // allow coercions for other scalar types
53   - // 17-Jan-2018, tatu: Related to [databind#1853] avoid FIELD_NAME by ensuring it's
54   - // "real" scalar
  51 +
55 52 if (t.isScalarValue()) {
56 53 String text = p.getValueAsString();
57   - return getCleanText(text);
  54 + return xssCleaner.clean(text);
58 55 }
59 56 return (String) ctxt.handleUnexpectedToken(_valueClass, p);
60 57 }
61   -
62   - private String getCleanText(String text) {
63   - if (text == null) {
64   - return null;
65   - }
66   - return xssProperties.isEnable() ? xssCleaner.clean(text) : text;
67   - }
68   -
69 58 }
70 59  
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/json/XssStringJsonSerializer.java deleted
1   -package cn.iocoder.yudao.framework.web.core.json;
2   -
3   -import cn.iocoder.yudao.framework.web.config.XssProperties;
4   -import cn.iocoder.yudao.framework.web.core.clean.XssCleaner;
5   -import com.fasterxml.jackson.core.JsonGenerator;
6   -import com.fasterxml.jackson.databind.JsonSerializer;
7   -import com.fasterxml.jackson.databind.SerializerProvider;
8   -import lombok.AllArgsConstructor;
9   -
10   -import java.io.IOException;
11   -
12   -/**
13   - * XSS过滤 jackson 序列化器
14   - *
15   - * 参考 ballcat 实现
16   - */
17   -@AllArgsConstructor
18   -public class XssStringJsonSerializer extends JsonSerializer<String> {
19   -
20   - private final XssCleaner xssCleaner;
21   - private final XssProperties xssProperties;
22   -
23   -
24   - @Override
25   - public Class<String> handledType() {
26   - return String.class;
27   - }
28   -
29   - @Override
30   - public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
31   - throws IOException {
32   - if (value != null) {
33   - // 开启 Xss 才进行处理
34   - if (xssProperties.isEnable()) {
35   - value = xssCleaner.clean(value);
36   - }
37   - jsonGenerator.writeString(value);
38   - }
39   - }
40   -
41   -}
42   -