Browse Source

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

gaibu 2 years ago
parent
commit
099754c26e

+ 6 - 5
yudao-dependencies/pom.xml

@@ -395,11 +395,6 @@
             <!-- 工作流相关结束 -->
 
             <!-- 工具类相关 -->
-            <dependency>
-                <groupId>org.jsoup</groupId>
-                <artifactId>jsoup</artifactId>
-                <version>${jsoup.version}</version>
-            </dependency>
             <dependency>
                 <groupId>cn.iocoder.boot</groupId>
                 <artifactId>yudao-common</artifactId>
@@ -528,6 +523,12 @@
                 <version>${ip2region.version}</version>
             </dependency>
 
+            <dependency>
+                <groupId>org.jsoup</groupId>
+                <artifactId>jsoup</artifactId>
+                <version>${jsoup.version}</version>
+            </dependency>
+
             <!-- 三方云服务相关 -->
             <dependency>
                 <groupId>com.squareup.okio</groupId>

+ 0 - 4
yudao-framework/yudao-common/pom.xml

@@ -133,10 +133,6 @@
             <artifactId>transmittable-thread-local</artifactId>
         </dependency>
 
-        <dependency>
-            <groupId>org.jsoup</groupId>
-            <artifactId>jsoup</artifactId>
-        </dependency>
     </dependencies>
 
 </project>

+ 5 - 0
yudao-framework/yudao-spring-boot-starter-web/pom.xml

@@ -67,6 +67,11 @@
             <scope>provided</scope> <!-- 设置为 provided,主要是 GlobalExceptionHandler 使用 -->
         </dependency>
 
+        <!-- xss -->
+        <dependency>
+            <groupId>org.jsoup</groupId>
+            <artifactId>jsoup</artifactId>
+        </dependency>
     </dependencies>
 
 </project>

+ 4 - 4
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 {
      *
      * @return XssCleaner
      */
-    @ConditionalOnMissingBean(XssCleaner.class)
     @Bean
+    @ConditionalOnMissingBean(XssCleaner.class)
     public XssCleaner xssCleaner() {
         return new JsoupXssCleaner();
     }
@@ -145,12 +145,12 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer {
     @Bean
     @ConditionalOnMissingBean(name = "xssJacksonCustomizer")
     @ConditionalOnBean(ObjectMapper.class)
-    public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssCleaner xssCleaner, XssProperties xssProperties) {
+    @ConditionalOnProperty(value = "yudao.xss.enable", havingValue = "true")
+    public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssCleaner xssCleaner) {
         // 在反序列化时进行 xss 过滤,可以替换使用 XssStringJsonSerializer,在序列化时进行处理
-        return builder -> builder.deserializerByType(String.class, new XssStringJsonDeserializer(xssCleaner, xssProperties));
+        return builder -> builder.deserializerByType(String.class, new XssStringJsonDeserializer(xssCleaner));
     }
 
-
     private static <T extends Filter> FilterRegistrationBean<T> createFilterBean(T filter, Integer order) {
         FilterRegistrationBean<T> bean = new FilterRegistrationBean<>(filter);
         bean.setOrder(order);

+ 8 - 9
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;
 import org.jsoup.nodes.Document;
 import org.jsoup.safety.Safelist;
 
+/**
+ * jsonp 过滤字符串
+ */
 public class JsoupXssCleaner implements XssCleaner {
 
     private final Safelist safelist;
@@ -37,19 +40,15 @@ public class JsoupXssCleaner implements XssCleaner {
     }
 
     /**
-     * <p>
      * 构建一个 Xss 清理的 Safelist 规则。
-     * </p>
-     *
-     * <ul>
      * 基于 Safelist#relaxed() 的基础上:
-     * <li>扩展支持了 style 和 class 属性</li>
-     * <li>a 标签额外支持了 target 属性</li>
-     * <li>img 标签额外支持了 data 协议,便于支持 base64</li>
-     * </ul>
+     * 1. 扩展支持了 style 和 class 属性
+     * 2. a 标签额外支持了 target 属性
+     * 3. img 标签额外支持了 data 协议,便于支持 base64
+     *
      * @return Safelist
      */
-    protected Safelist buildSafelist() {
+    private Safelist buildSafelist() {
         // 使用 jsoup 提供的默认的
         Safelist relaxedSafelist = Safelist.relaxed();
         // 富文本编辑时一些样式是使用 style 来进行实现的

+ 1 - 0
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;
  * 对 html 文本中的有 Xss 风险的数据进行清理
  */
 public interface XssCleaner {
+
     /**
      * 清理有 Xss 风险的文本
      *

+ 4 - 0
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 {
         this.xssCleaner = xssCleaner;
     }
 
+    // ============================ parameter ============================
     @Override
     public Map<String, String[]> getParameterMap() {
         Map<String, String[]> map = new LinkedHashMap<>();
@@ -57,6 +58,7 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
         return xssCleaner.clean(value);
     }
 
+    // ============================ attribute ============================
     @Override
     public Object getAttribute(String name) {
         Object value = super.getAttribute(name);
@@ -66,6 +68,7 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
         return value;
     }
 
+    // ============================ header ============================
     @Override
     public String getHeader(String name) {
         String value = super.getHeader(name);
@@ -75,6 +78,7 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
         return xssCleaner.clean(value);
     }
 
+    // ============================ queryString ============================
     @Override
     public String getQueryString() {
         String value = super.getQueryString();

+ 6 - 17
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/json/XssStringJsonDeserializer.java

@@ -1,6 +1,5 @@
 package cn.iocoder.yudao.framework.web.core.json;
 
-import cn.iocoder.yudao.framework.web.config.XssProperties;
 import cn.iocoder.yudao.framework.web.core.clean.XssCleaner;
 import com.fasterxml.jackson.core.JsonParser;
 import com.fasterxml.jackson.core.JsonToken;
@@ -12,21 +11,21 @@ import lombok.extern.slf4j.Slf4j;
 import java.io.IOException;
 
 /**
- * XSS过滤 jackson 反序列化器
+ * XSS 过滤 jackson 反序列化器。
+ * 在反序列化的过程中,会对字符串进行 XSS 过滤。
  *
- * 参考 ballcat 实现
+ * @author Hccake
  */
 @Slf4j
 @AllArgsConstructor
 public class XssStringJsonDeserializer extends StringDeserializer {
 
     private final XssCleaner xssCleaner;
-    private final XssProperties xssProperties;
 
     @Override
     public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
         if (p.hasToken(JsonToken.VALUE_STRING)) {
-            return getCleanText(p.getText());
+            return xssCleaner.clean(p.getText());
         }
         JsonToken t = p.currentToken();
         // [databind#381]
@@ -49,22 +48,12 @@ public class XssStringJsonDeserializer extends StringDeserializer {
         if (t == JsonToken.START_OBJECT) {
             return ctxt.extractScalarFromObject(p, this, _valueClass);
         }
-        // allow coercions for other scalar types
-        // 17-Jan-2018, tatu: Related to [databind#1853] avoid FIELD_NAME by ensuring it's
-        // "real" scalar
+
         if (t.isScalarValue()) {
             String text = p.getValueAsString();
-            return getCleanText(text);
+            return xssCleaner.clean(text);
         }
         return (String) ctxt.handleUnexpectedToken(_valueClass, p);
     }
-
-    private String getCleanText(String text) {
-        if (text == null) {
-            return null;
-        }
-        return xssProperties.isEnable() ? xssCleaner.clean(text) : text;
-    }
-
 }
 

+ 0 - 42
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/json/XssStringJsonSerializer.java

@@ -1,42 +0,0 @@
-package cn.iocoder.yudao.framework.web.core.json;
-
-import cn.iocoder.yudao.framework.web.config.XssProperties;
-import cn.iocoder.yudao.framework.web.core.clean.XssCleaner;
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import lombok.AllArgsConstructor;
-
-import java.io.IOException;
-
-/**
- * XSS过滤 jackson 序列化器
- *
- * 参考 ballcat 实现
- */
-@AllArgsConstructor
-public class XssStringJsonSerializer extends JsonSerializer<String> {
-
-    private final XssCleaner xssCleaner;
-    private final XssProperties xssProperties;
-
-
-    @Override
-    public Class<String> handledType() {
-        return String.class;
-    }
-
-    @Override
-    public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
-            throws IOException {
-        if (value != null) {
-            // 开启 Xss 才进行处理
-            if (xssProperties.isEnable()) {
-                value = xssCleaner.clean(value);
-            }
-            jsonGenerator.writeString(value);
-        }
-    }
-
-}
-