!253 修复:非法请求使过滤器失效,出现严重安全问题
* BaseUrlFilter 修改过滤全部路径,保证 BaseUrlFilter 优于UrlCheckFilter 执行 * 清除无用 html * 非法请求过滤器: 修复请求 path 中包含 // 或者以 / 结尾导致其它过滤器失效,对请求进行重定向 * 非法请求过滤器: 替换 getRequestURI() 为 getServletPath() * 非法请求过滤器: 截取 context-path * 非法请求过滤器: 去除 context-path * 非法请求过滤器: 排除首页path "/" * 非法请求过滤器: 请求地址中包含"//"或者以"/"结尾时导致其他过滤器失效,比如 TrustHostFilter
This commit is contained in:
@ -30,11 +30,13 @@ public class WebConfig implements WebMvcConfigurer {
|
|||||||
registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/","classpath:/resources/","classpath:/static/","classpath:/public/","file:" + filePath);
|
registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/","classpath:/resources/","classpath:/static/","classpath:/public/","file:" + filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public FilterRegistrationBean<ChinesePathFilter> getChinesePathFilter() {
|
public FilterRegistrationBean<ChinesePathFilter> getChinesePathFilter() {
|
||||||
ChinesePathFilter filter = new ChinesePathFilter();
|
ChinesePathFilter filter = new ChinesePathFilter();
|
||||||
FilterRegistrationBean<ChinesePathFilter> registrationBean = new FilterRegistrationBean<>();
|
FilterRegistrationBean<ChinesePathFilter> registrationBean = new FilterRegistrationBean<>();
|
||||||
registrationBean.setFilter(filter);
|
registrationBean.setFilter(filter);
|
||||||
|
registrationBean.setOrder(10);
|
||||||
return registrationBean;
|
return registrationBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,14 +69,20 @@ public class WebConfig implements WebMvcConfigurer {
|
|||||||
@Bean
|
@Bean
|
||||||
public FilterRegistrationBean<BaseUrlFilter> getBaseUrlFilter() {
|
public FilterRegistrationBean<BaseUrlFilter> getBaseUrlFilter() {
|
||||||
Set<String> filterUri = new HashSet<>();
|
Set<String> filterUri = new HashSet<>();
|
||||||
filterUri.add("/index");
|
|
||||||
filterUri.add("/");
|
|
||||||
filterUri.add("/onlinePreview");
|
|
||||||
filterUri.add("/picturesPreview");
|
|
||||||
BaseUrlFilter filter = new BaseUrlFilter();
|
BaseUrlFilter filter = new BaseUrlFilter();
|
||||||
FilterRegistrationBean<BaseUrlFilter> registrationBean = new FilterRegistrationBean<>();
|
FilterRegistrationBean<BaseUrlFilter> registrationBean = new FilterRegistrationBean<>();
|
||||||
registrationBean.setFilter(filter);
|
registrationBean.setFilter(filter);
|
||||||
registrationBean.setUrlPatterns(filterUri);
|
registrationBean.setUrlPatterns(filterUri);
|
||||||
|
registrationBean.setOrder(20);
|
||||||
|
return registrationBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public FilterRegistrationBean<UrlCheckFilter> getUrlCheckFilter() {
|
||||||
|
UrlCheckFilter filter = new UrlCheckFilter();
|
||||||
|
FilterRegistrationBean<UrlCheckFilter> registrationBean = new FilterRegistrationBean<>();
|
||||||
|
registrationBean.setFilter(filter);
|
||||||
|
registrationBean.setOrder(30);
|
||||||
return registrationBean;
|
return registrationBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,52 @@
|
|||||||
|
package cn.keking.web.filter;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import javax.servlet.*;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @date 2023/11/30
|
||||||
|
*/
|
||||||
|
public class UrlCheckFilter implements Filter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||||
|
|
||||||
|
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
||||||
|
String servletPath = httpServletRequest.getServletPath();
|
||||||
|
|
||||||
|
boolean redirect = false;
|
||||||
|
|
||||||
|
// servletPath 中不能包含 //
|
||||||
|
if (servletPath.contains("//")) {
|
||||||
|
servletPath = servletPath.replaceAll("//+", "/");
|
||||||
|
redirect = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不能以 / 结尾,同时考虑 **首页** 的特殊性
|
||||||
|
if (servletPath.endsWith("/") && servletPath.length() > 1) {
|
||||||
|
servletPath = servletPath.substring(0, servletPath.length() - 1);
|
||||||
|
redirect = true;
|
||||||
|
}
|
||||||
|
if (redirect) {
|
||||||
|
String redirectUrl;
|
||||||
|
if (StringUtils.isBlank(BaseUrlFilter.getBaseUrl())) {
|
||||||
|
// 正常 BaseUrlFilter 有限此 Filter 执行,不会执行到此
|
||||||
|
redirectUrl = httpServletRequest.getContextPath() + servletPath;
|
||||||
|
} else {
|
||||||
|
if (BaseUrlFilter.getBaseUrl().endsWith("/") && servletPath.startsWith("/")) {
|
||||||
|
// BaseUrlFilter.getBaseUrl() 以 / 结尾,servletPath 以 / 开头,需再去除一次 //
|
||||||
|
redirectUrl = BaseUrlFilter.getBaseUrl() + servletPath.substring(1);
|
||||||
|
} else {
|
||||||
|
redirectUrl = BaseUrlFilter.getBaseUrl() + servletPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
((HttpServletResponse) response).sendRedirect(redirectUrl + "?" + httpServletRequest.getQueryString());
|
||||||
|
} else {
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user