mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 10:18:42 +08:00 
			
		
		
		
	!383 优化 xss 的代码实现,独立 xss 包
Merge pull request !383 from 芋道源码/feature/dev-yunai
This commit is contained in:
		| @@ -2,27 +2,18 @@ package cn.iocoder.yudao.framework.web.config; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService; | ||||
| import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; | ||||
| import cn.iocoder.yudao.framework.web.core.clean.JsoupXssCleaner; | ||||
| import cn.iocoder.yudao.framework.web.core.clean.XssCleaner; | ||||
| import cn.iocoder.yudao.framework.web.core.filter.CacheRequestBodyFilter; | ||||
| import cn.iocoder.yudao.framework.web.core.filter.DemoFilter; | ||||
| import cn.iocoder.yudao.framework.web.core.filter.XssFilter; | ||||
| import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler; | ||||
| import cn.iocoder.yudao.framework.web.core.handler.GlobalResponseBodyHandler; | ||||
| import cn.iocoder.yudao.framework.web.core.json.XssStringJsonDeserializer; | ||||
| import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; | ||||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||||
| import org.springframework.beans.factory.annotation.Value; | ||||
| import org.springframework.boot.autoconfigure.AutoConfiguration; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||||
| import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; | ||||
| import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||||
| import org.springframework.boot.web.servlet.FilterRegistrationBean; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.util.AntPathMatcher; | ||||
| import org.springframework.util.PathMatcher; | ||||
| import org.springframework.web.bind.annotation.RestController; | ||||
| import org.springframework.web.cors.CorsConfiguration; | ||||
| import org.springframework.web.cors.UrlBasedCorsConfigurationSource; | ||||
| @@ -34,7 +25,7 @@ import javax.annotation.Resource; | ||||
| import javax.servlet.Filter; | ||||
|  | ||||
| @AutoConfiguration | ||||
| @EnableConfigurationProperties({WebProperties.class, XssProperties.class}) | ||||
| @EnableConfigurationProperties(WebProperties.class) | ||||
| public class YudaoWebAutoConfiguration implements WebMvcConfigurer { | ||||
|  | ||||
|     @Resource | ||||
| @@ -107,15 +98,6 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer { | ||||
|         return createFilterBean(new CacheRequestBodyFilter(), WebFilterOrderEnum.REQUEST_BODY_CACHE_FILTER); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 创建 XssFilter Bean,解决 Xss 安全问题 | ||||
|      */ | ||||
|     @Bean | ||||
|     @ConditionalOnBean(XssCleaner.class) | ||||
|     public FilterRegistrationBean<XssFilter> xssFilter(XssProperties properties, PathMatcher pathMatcher, XssCleaner xssCleaner) { | ||||
|         return createFilterBean(new XssFilter(properties, pathMatcher, xssCleaner), WebFilterOrderEnum.XSS_FILTER); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 创建 DemoFilter Bean,演示模式 | ||||
|      */ | ||||
| @@ -125,33 +107,7 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer { | ||||
|         return createFilterBean(new DemoFilter(), WebFilterOrderEnum.DEMO_FILTER); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Xss 清理者 | ||||
|      * | ||||
|      * @return XssCleaner | ||||
|      */ | ||||
|     @Bean | ||||
|     @ConditionalOnMissingBean(XssCleaner.class) | ||||
|     public XssCleaner xssCleaner() { | ||||
|         return new JsoupXssCleaner(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 注册 Jackson 的序列化器,用于处理 json 类型参数的 xss 过滤 | ||||
|      * | ||||
|      * @return Jackson2ObjectMapperBuilderCustomizer | ||||
|      */ | ||||
|     @Bean | ||||
|     @ConditionalOnMissingBean(name = "xssJacksonCustomizer") | ||||
|     @ConditionalOnBean(ObjectMapper.class) | ||||
|     @ConditionalOnProperty(value = "yudao.xss.enable", havingValue = "true") | ||||
|     public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssCleaner xssCleaner) { | ||||
|         // 在反序列化时进行 xss 过滤,可以替换使用 XssStringJsonSerializer,在序列化时进行处理 | ||||
|         return builder -> builder.deserializerByType(String.class, new XssStringJsonDeserializer(xssCleaner)); | ||||
|     } | ||||
|  | ||||
|     private static <T extends Filter> FilterRegistrationBean<T> createFilterBean(T filter, Integer order) { | ||||
|     public static <T extends Filter> FilterRegistrationBean<T> createFilterBean(T filter, Integer order) { | ||||
|         FilterRegistrationBean<T> bean = new FilterRegistrationBean<>(filter); | ||||
|         bean.setOrder(order); | ||||
|         return bean; | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| package cn.iocoder.yudao.framework.web.config; | ||||
| package cn.iocoder.yudao.framework.xss.config; | ||||
| 
 | ||||
| import lombok.Data; | ||||
| import org.springframework.boot.context.properties.ConfigurationProperties; | ||||
| @@ -0,0 +1,60 @@ | ||||
| package cn.iocoder.yudao.framework.xss.config; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; | ||||
| import cn.iocoder.yudao.framework.xss.core.clean.JsoupXssCleaner; | ||||
| import cn.iocoder.yudao.framework.xss.core.clean.XssCleaner; | ||||
| import cn.iocoder.yudao.framework.xss.core.filter.XssFilter; | ||||
| import cn.iocoder.yudao.framework.xss.core.json.XssStringJsonDeserializer; | ||||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||||
| import org.springframework.boot.autoconfigure.AutoConfiguration; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||||
| import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; | ||||
| import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||||
| import org.springframework.boot.web.servlet.FilterRegistrationBean; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.util.PathMatcher; | ||||
| import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.web.config.YudaoWebAutoConfiguration.createFilterBean; | ||||
|  | ||||
| @AutoConfiguration | ||||
| @EnableConfigurationProperties(XssProperties.class) | ||||
| public class YudaoXssAutoConfiguration implements WebMvcConfigurer { | ||||
|  | ||||
|     /** | ||||
|      * Xss 清理者 | ||||
|      * | ||||
|      * @return XssCleaner | ||||
|      */ | ||||
|     @Bean | ||||
|     @ConditionalOnMissingBean(XssCleaner.class) | ||||
|     public XssCleaner xssCleaner() { | ||||
|         return new JsoupXssCleaner(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 注册 Jackson 的序列化器,用于处理 json 类型参数的 xss 过滤 | ||||
|      * | ||||
|      * @return Jackson2ObjectMapperBuilderCustomizer | ||||
|      */ | ||||
|     @Bean | ||||
|     @ConditionalOnMissingBean(name = "xssJacksonCustomizer") | ||||
|     @ConditionalOnBean(ObjectMapper.class) | ||||
|     @ConditionalOnProperty(value = "yudao.xss.enable", havingValue = "true") | ||||
|     public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssCleaner xssCleaner) { | ||||
|         // 在反序列化时进行 xss 过滤,可以替换使用 XssStringJsonSerializer,在序列化时进行处理 | ||||
|         return builder -> builder.deserializerByType(String.class, new XssStringJsonDeserializer(xssCleaner)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 创建 XssFilter Bean,解决 Xss 安全问题 | ||||
|      */ | ||||
|     @Bean | ||||
|     @ConditionalOnBean(XssCleaner.class) | ||||
|     public FilterRegistrationBean<XssFilter> xssFilter(XssProperties properties, PathMatcher pathMatcher, XssCleaner xssCleaner) { | ||||
|         return createFilterBean(new XssFilter(properties, pathMatcher, xssCleaner), WebFilterOrderEnum.XSS_FILTER); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,11 +1,11 @@ | ||||
| package cn.iocoder.yudao.framework.web.core.clean; | ||||
| package cn.iocoder.yudao.framework.xss.core.clean; | ||||
| 
 | ||||
| import org.jsoup.Jsoup; | ||||
| import org.jsoup.nodes.Document; | ||||
| import org.jsoup.safety.Safelist; | ||||
| 
 | ||||
| /** | ||||
|  * jsonp 过滤字符串 | ||||
|  * 基于 JSONP 实现 XSS 过滤字符串 | ||||
|  */ | ||||
| public class JsoupXssCleaner implements XssCleaner { | ||||
| 
 | ||||
| @@ -24,21 +24,6 @@ public class JsoupXssCleaner implements XssCleaner { | ||||
|         this.baseUri = ""; | ||||
|     } | ||||
| 
 | ||||
|     public JsoupXssCleaner(Safelist safelist) { | ||||
|         this.safelist = safelist; | ||||
|         this.baseUri = ""; | ||||
|     } | ||||
| 
 | ||||
|     public JsoupXssCleaner(String baseUri) { | ||||
|         this.safelist = buildSafelist(); | ||||
|         this.baseUri = baseUri; | ||||
|     } | ||||
| 
 | ||||
|     public JsoupXssCleaner(Safelist safelist, String baseUri) { | ||||
|         this.safelist = safelist; | ||||
|         this.baseUri = baseUri; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 构建一个 Xss 清理的 Safelist 规则。 | ||||
|      * 基于 Safelist#relaxed() 的基础上: | ||||
| @@ -67,7 +52,6 @@ public class JsoupXssCleaner implements XssCleaner { | ||||
|         // 虽然可以重写 WhiteList#isSafeAttribute 来处理,但是有隐患,所以暂时不支持相对路径 | ||||
|         // WHITELIST.removeProtocols("a", "href", "ftp", "http", "https", "mailto"); | ||||
|         // WHITELIST.removeProtocols("img", "src", "http", "https"); | ||||
| 
 | ||||
|         return relaxedSafelist; | ||||
|     } | ||||
| 
 | ||||
| @@ -1,4 +1,4 @@ | ||||
| package cn.iocoder.yudao.framework.web.core.clean; | ||||
| package cn.iocoder.yudao.framework.xss.core.clean; | ||||
| 
 | ||||
| /** | ||||
|  * 对 html 文本中的有 Xss 风险的数据进行清理 | ||||
| @@ -12,4 +12,5 @@ public interface XssCleaner { | ||||
|      * @return 清理后的 html | ||||
|      */ | ||||
|     String clean(String html); | ||||
| 
 | ||||
| } | ||||
| @@ -1,7 +1,7 @@ | ||||
| package cn.iocoder.yudao.framework.web.core.filter; | ||||
| package cn.iocoder.yudao.framework.xss.core.filter; | ||||
| 
 | ||||
| import cn.iocoder.yudao.framework.web.config.XssProperties; | ||||
| import cn.iocoder.yudao.framework.web.core.clean.XssCleaner; | ||||
| import cn.iocoder.yudao.framework.xss.config.XssProperties; | ||||
| import cn.iocoder.yudao.framework.xss.core.clean.XssCleaner; | ||||
| import lombok.AllArgsConstructor; | ||||
| import org.springframework.util.PathMatcher; | ||||
| import org.springframework.web.filter.OncePerRequestFilter; | ||||
| @@ -14,8 +14,6 @@ import java.io.IOException; | ||||
| 
 | ||||
| /** | ||||
|  * Xss 过滤器 | ||||
|  * <p> | ||||
|  * 对 Xss 不了解的胖友,可以看看 http://www.iocoder.cn/Fight/The-new-girl-asked-me-why-AJAX-requests-are-not-secure-I-did-not-answer/ | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| @@ -1,6 +1,6 @@ | ||||
| package cn.iocoder.yudao.framework.web.core.filter; | ||||
| package cn.iocoder.yudao.framework.xss.core.filter; | ||||
| 
 | ||||
| import cn.iocoder.yudao.framework.web.core.clean.XssCleaner; | ||||
| import cn.iocoder.yudao.framework.xss.core.clean.XssCleaner; | ||||
| 
 | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletRequestWrapper; | ||||
| @@ -13,6 +13,7 @@ import java.util.Map; | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| public class XssRequestWrapper extends HttpServletRequestWrapper { | ||||
| 
 | ||||
|     private final XssCleaner xssCleaner; | ||||
| 
 | ||||
|     public XssRequestWrapper(HttpServletRequest request, XssCleaner xssCleaner) { | ||||
| @@ -1,6 +1,6 @@ | ||||
| package cn.iocoder.yudao.framework.web.core.json; | ||||
| package cn.iocoder.yudao.framework.xss.core.json; | ||||
| 
 | ||||
| import cn.iocoder.yudao.framework.web.core.clean.XssCleaner; | ||||
| import cn.iocoder.yudao.framework.xss.core.clean.XssCleaner; | ||||
| import com.fasterxml.jackson.core.JsonParser; | ||||
| import com.fasterxml.jackson.core.JsonToken; | ||||
| import com.fasterxml.jackson.databind.DeserializationContext; | ||||
| @@ -0,0 +1,6 @@ | ||||
| /** | ||||
|  * 针对 XSS 的基础封装 | ||||
|  * | ||||
|  * XSS 说明:https://tech.meituan.com/2018/09/27/fe-security.html | ||||
|  */ | ||||
| package cn.iocoder.yudao.framework.xss; | ||||
| @@ -2,3 +2,4 @@ cn.iocoder.yudao.framework.apilog.config.YudaoApiLogAutoConfiguration | ||||
| cn.iocoder.yudao.framework.jackson.config.YudaoJacksonAutoConfiguration | ||||
| cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration | ||||
| cn.iocoder.yudao.framework.web.config.YudaoWebAutoConfiguration | ||||
| cn.iocoder.yudao.framework.xss.config.YudaoXssAutoConfiguration | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 芋道源码
					芋道源码