Commit 7d0e20be524a78861f9640eef45554bfb782774f
Committed by
Gitee
!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,27 +2,18 @@ package cn.iocoder.yudao.framework.web.config; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService; | 3 | import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService; |
| 4 | import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; | 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 | import cn.iocoder.yudao.framework.web.core.filter.CacheRequestBodyFilter; | 5 | import cn.iocoder.yudao.framework.web.core.filter.CacheRequestBodyFilter; |
| 8 | import cn.iocoder.yudao.framework.web.core.filter.DemoFilter; | 6 | import cn.iocoder.yudao.framework.web.core.filter.DemoFilter; |
| 9 | -import cn.iocoder.yudao.framework.web.core.filter.XssFilter; | ||
| 10 | import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler; | 7 | import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler; |
| 11 | import cn.iocoder.yudao.framework.web.core.handler.GlobalResponseBodyHandler; | 8 | import cn.iocoder.yudao.framework.web.core.handler.GlobalResponseBodyHandler; |
| 12 | -import cn.iocoder.yudao.framework.web.core.json.XssStringJsonDeserializer; | ||
| 13 | import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; | 9 | import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; |
| 14 | -import com.fasterxml.jackson.databind.ObjectMapper; | ||
| 15 | import org.springframework.beans.factory.annotation.Value; | 10 | import org.springframework.beans.factory.annotation.Value; |
| 16 | import org.springframework.boot.autoconfigure.AutoConfiguration; | 11 | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| 17 | -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; | ||
| 18 | -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||
| 19 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | 12 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| 20 | -import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; | ||
| 21 | import org.springframework.boot.context.properties.EnableConfigurationProperties; | 13 | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| 22 | import org.springframework.boot.web.servlet.FilterRegistrationBean; | 14 | import org.springframework.boot.web.servlet.FilterRegistrationBean; |
| 23 | import org.springframework.context.annotation.Bean; | 15 | import org.springframework.context.annotation.Bean; |
| 24 | import org.springframework.util.AntPathMatcher; | 16 | import org.springframework.util.AntPathMatcher; |
| 25 | -import org.springframework.util.PathMatcher; | ||
| 26 | import org.springframework.web.bind.annotation.RestController; | 17 | import org.springframework.web.bind.annotation.RestController; |
| 27 | import org.springframework.web.cors.CorsConfiguration; | 18 | import org.springframework.web.cors.CorsConfiguration; |
| 28 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; | 19 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; |
| @@ -34,7 +25,7 @@ import javax.annotation.Resource; | @@ -34,7 +25,7 @@ import javax.annotation.Resource; | ||
| 34 | import javax.servlet.Filter; | 25 | import javax.servlet.Filter; |
| 35 | 26 | ||
| 36 | @AutoConfiguration | 27 | @AutoConfiguration |
| 37 | -@EnableConfigurationProperties({WebProperties.class, XssProperties.class}) | 28 | +@EnableConfigurationProperties(WebProperties.class) |
| 38 | public class YudaoWebAutoConfiguration implements WebMvcConfigurer { | 29 | public class YudaoWebAutoConfiguration implements WebMvcConfigurer { |
| 39 | 30 | ||
| 40 | @Resource | 31 | @Resource |
| @@ -108,15 +99,6 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer { | @@ -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 | * 创建 DemoFilter Bean,演示模式 | 102 | * 创建 DemoFilter Bean,演示模式 |
| 121 | */ | 103 | */ |
| 122 | @Bean | 104 | @Bean |
| @@ -125,33 +107,7 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer { | @@ -125,33 +107,7 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer { | ||
| 125 | return createFilterBean(new DemoFilter(), WebFilterOrderEnum.DEMO_FILTER); | 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 | FilterRegistrationBean<T> bean = new FilterRegistrationBean<>(filter); | 111 | FilterRegistrationBean<T> bean = new FilterRegistrationBean<>(filter); |
| 156 | bean.setOrder(order); | 112 | bean.setOrder(order); |
| 157 | return bean; | 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 | import lombok.Data; | 3 | import lombok.Data; |
| 4 | import org.springframework.boot.context.properties.ConfigurationProperties; | 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 | import org.jsoup.Jsoup; | 3 | import org.jsoup.Jsoup; |
| 4 | import org.jsoup.nodes.Document; | 4 | import org.jsoup.nodes.Document; |
| 5 | import org.jsoup.safety.Safelist; | 5 | import org.jsoup.safety.Safelist; |
| 6 | 6 | ||
| 7 | /** | 7 | /** |
| 8 | - * jsonp 过滤字符串 | 8 | + * 基于 JSONP 实现 XSS 过滤字符串 |
| 9 | */ | 9 | */ |
| 10 | public class JsoupXssCleaner implements XssCleaner { | 10 | public class JsoupXssCleaner implements XssCleaner { |
| 11 | 11 | ||
| @@ -24,21 +24,6 @@ public class JsoupXssCleaner implements XssCleaner { | @@ -24,21 +24,6 @@ public class JsoupXssCleaner implements XssCleaner { | ||
| 24 | this.baseUri = ""; | 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 | * 构建一个 Xss 清理的 Safelist 规则。 | 28 | * 构建一个 Xss 清理的 Safelist 规则。 |
| 44 | * 基于 Safelist#relaxed() 的基础上: | 29 | * 基于 Safelist#relaxed() 的基础上: |
| @@ -67,7 +52,6 @@ public class JsoupXssCleaner implements XssCleaner { | @@ -67,7 +52,6 @@ public class JsoupXssCleaner implements XssCleaner { | ||
| 67 | // 虽然可以重写 WhiteList#isSafeAttribute 来处理,但是有隐患,所以暂时不支持相对路径 | 52 | // 虽然可以重写 WhiteList#isSafeAttribute 来处理,但是有隐患,所以暂时不支持相对路径 |
| 68 | // WHITELIST.removeProtocols("a", "href", "ftp", "http", "https", "mailto"); | 53 | // WHITELIST.removeProtocols("a", "href", "ftp", "http", "https", "mailto"); |
| 69 | // WHITELIST.removeProtocols("img", "src", "http", "https"); | 54 | // WHITELIST.removeProtocols("img", "src", "http", "https"); |
| 70 | - | ||
| 71 | return relaxedSafelist; | 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 | * 对 html 文本中的有 Xss 风险的数据进行清理 | 4 | * 对 html 文本中的有 Xss 风险的数据进行清理 |
| @@ -12,4 +12,5 @@ public interface XssCleaner { | @@ -12,4 +12,5 @@ public interface XssCleaner { | ||
| 12 | * @return 清理后的 html | 12 | * @return 清理后的 html |
| 13 | */ | 13 | */ |
| 14 | String clean(String html); | 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 | import lombok.AllArgsConstructor; | 5 | import lombok.AllArgsConstructor; |
| 6 | import org.springframework.util.PathMatcher; | 6 | import org.springframework.util.PathMatcher; |
| 7 | import org.springframework.web.filter.OncePerRequestFilter; | 7 | import org.springframework.web.filter.OncePerRequestFilter; |
| @@ -14,8 +14,6 @@ import java.io.IOException; | @@ -14,8 +14,6 @@ import java.io.IOException; | ||
| 14 | 14 | ||
| 15 | /** | 15 | /** |
| 16 | * Xss 过滤器 | 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 | * @author 芋道源码 | 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 | import javax.servlet.http.HttpServletRequest; | 5 | import javax.servlet.http.HttpServletRequest; |
| 6 | import javax.servlet.http.HttpServletRequestWrapper; | 6 | import javax.servlet.http.HttpServletRequestWrapper; |
| @@ -13,6 +13,7 @@ import java.util.Map; | @@ -13,6 +13,7 @@ import java.util.Map; | ||
| 13 | * @author 芋道源码 | 13 | * @author 芋道源码 |
| 14 | */ | 14 | */ |
| 15 | public class XssRequestWrapper extends HttpServletRequestWrapper { | 15 | public class XssRequestWrapper extends HttpServletRequestWrapper { |
| 16 | + | ||
| 16 | private final XssCleaner xssCleaner; | 17 | private final XssCleaner xssCleaner; |
| 17 | 18 | ||
| 18 | public XssRequestWrapper(HttpServletRequest request, XssCleaner xssCleaner) { | 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 | import com.fasterxml.jackson.core.JsonParser; | 4 | import com.fasterxml.jackson.core.JsonParser; |
| 5 | import com.fasterxml.jackson.core.JsonToken; | 5 | import com.fasterxml.jackson.core.JsonToken; |
| 6 | import com.fasterxml.jackson.databind.DeserializationContext; | 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
yudao-framework/yudao-spring-boot-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
| 1 | cn.iocoder.yudao.framework.apilog.config.YudaoApiLogAutoConfiguration | 1 | cn.iocoder.yudao.framework.apilog.config.YudaoApiLogAutoConfiguration |
| 2 | cn.iocoder.yudao.framework.jackson.config.YudaoJacksonAutoConfiguration | 2 | cn.iocoder.yudao.framework.jackson.config.YudaoJacksonAutoConfiguration |
| 3 | cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration | 3 | cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration |
| 4 | -cn.iocoder.yudao.framework.web.config.YudaoWebAutoConfiguration | ||
| 5 | \ No newline at end of file | 4 | \ No newline at end of file |
| 5 | +cn.iocoder.yudao.framework.web.config.YudaoWebAutoConfiguration | ||
| 6 | +cn.iocoder.yudao.framework.xss.config.YudaoXssAutoConfiguration |