xss问题修正

This commit is contained in:
liweiyi 2024-09-27 15:51:09 +08:00
parent bfe5f1ee68
commit 059b7fe848
8 changed files with 49 additions and 93 deletions

View File

@ -237,12 +237,6 @@ mybatis-plus:
xss:
# 过滤开关
enabled: true
mode: clean
# 过滤链接
urlPatterns:
- /system/*
- /monitor/*
- /tool/*
xxl:
job:

View File

@ -220,12 +220,6 @@ mybatis-plus:
xss:
# 过滤开关
enabled: true
mode: clean
# 过滤链接
urlPatterns:
- /system/*
- /monitor/*
- /tool/*
xxl:
job:

View File

@ -17,10 +17,10 @@ package com.chestnut.common.extend.config;
import com.chestnut.common.extend.config.properties.XssProperties;
import com.chestnut.common.extend.xss.XssDeserializer;
import com.chestnut.common.extend.xss.XssFilter;
import com.chestnut.common.extend.xss.XssInterceptor;
import com.chestnut.common.utils.StringUtils;
import com.chestnut.common.extend.xss.XssOncePerRequestFilter;
import lombok.RequiredArgsConstructor;
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;
@ -30,7 +30,6 @@ import org.springframework.core.Ordered;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Collections;
import java.util.List;
@RequiredArgsConstructor
@ -43,33 +42,23 @@ public class XssConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
if (xssProperties.isEnabled()) {
List<String> urlPatterns = xssProperties.getUrlPatterns();
if (StringUtils.isEmpty(urlPatterns)) {
urlPatterns = List.of("/**");
}
List<String> excludes = xssProperties.getExcludes();
if (StringUtils.isEmpty(excludes)) {
excludes = Collections.emptyList();
}
registry.addInterceptor(new XssInterceptor()).addPathPatterns(urlPatterns)
.excludePathPatterns(excludes).order(Ordered.HIGHEST_PRECEDENCE);
registry.addInterceptor(new XssInterceptor()).addPathPatterns(List.of("/**"))
.order(Ordered.HIGHEST_PRECEDENCE);
}
}
@Bean
public FilterRegistrationBean<XssFilter> filterRegistrationBean() {
FilterRegistrationBean<XssFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new XssFilter(xssProperties.getMode()));
@ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
public FilterRegistrationBean<XssOncePerRequestFilter> filterRegistrationBean() {
FilterRegistrationBean<XssOncePerRequestFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new XssOncePerRequestFilter(xssProperties.getMode()));
registrationBean.setName("ChestnutXSSFilter");
List<String> urlPatterns = xssProperties.getUrlPatterns();
if (StringUtils.isEmpty(urlPatterns)) {
urlPatterns = List.of("/*");
}
registrationBean.addUrlPatterns(urlPatterns.toArray(String[]::new));
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
@Bean
@ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
public Jackson2ObjectMapperBuilderCustomizer xssCustomizer() {
return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.deserializerByType(String.class,
new XssDeserializer(xssProperties.getMode()));

View File

@ -15,14 +15,10 @@
*/
package com.chestnut.common.extend.config.properties;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
import com.chestnut.common.extend.enums.XssMode;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Setter
@Getter
@ -37,15 +33,5 @@ public class XssProperties {
/**
* 处理方式
*/
private XssMode mode;
/**
* 不进行处理的路径
*/
private List<String> excludes;
/**
* 处理指定路径
*/
private List<String> urlPatterns;
private XssMode mode = XssMode.ESCAPE;
}

View File

@ -26,14 +26,14 @@ public class XssContextHolder {
private static final ThreadLocal<Boolean> CONTEXT = new ThreadLocal<>();
/**
* 默认false
* 默认true
*/
public static boolean isIgnore() {
return Objects.requireNonNullElse(CONTEXT.get(), false);
return Objects.requireNonNullElse(CONTEXT.get(), true);
}
public static void ignore() {
CONTEXT.set(true);
public static void ignore(Boolean ignore) {
CONTEXT.set(ignore);
}
public static void remove() {

View File

@ -1,29 +0,0 @@
package com.chestnut.common.extend.xss;
import com.chestnut.common.extend.enums.XssMode;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* XSSFilter
*
* @author 兮玥
* @email 190785909@qq.com
*/
public class XssFilter implements Filter {
private final XssMode xssMode;
public XssFilter(XssMode xssMode) {
this.xssMode = xssMode;
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
XssHttpServletRequestWrapper wrapper = new XssHttpServletRequestWrapper(request, xssMode);
filterChain.doFilter(wrapper, servletResponse);
}
}

View File

@ -21,23 +21,13 @@ import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import java.util.Objects;
public class XssInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (handler instanceof HandlerMethod handlerMethod) {
XssIgnore xssIgnore = handlerMethod.getMethodAnnotation(XssIgnore.class);
if (Objects.nonNull(xssIgnore)) {
XssContextHolder.ignore();
}
XssContextHolder.ignore(handlerMethod.hasMethodAnnotation(XssIgnore.class));
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
XssContextHolder.remove();
}
}

View File

@ -0,0 +1,32 @@
package com.chestnut.common.extend.xss;
import com.chestnut.common.extend.enums.XssMode;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
/**
* XSSFilter
*
* @author 兮玥
* @email 190785909@qq.com
*/
public class XssOncePerRequestFilter extends OncePerRequestFilter {
private final XssMode xssMode;
public XssOncePerRequestFilter(XssMode xssMode) {
this.xssMode = xssMode;
}
@Override
protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
XssHttpServletRequestWrapper wrapper = new XssHttpServletRequestWrapper(request, xssMode);
filterChain.doFilter(wrapper, response);
}
}