1、tomcat 组件-webfilter,存在两处逻辑漏洞,可以绕过限制
2、漏洞代码1
if (requestUrl != null && (requestUrl.contains("/doc.html") ||
requestUrl.contains("/register.html") || requestUrl.contains("/login.html"))) {
chain.doFilter(request, response);
return;
}
复现1
漏洞代码2
if (verify(ignoredList, requestUrl)) {
chain.doFilter(servletRequest, response);
return;
}
private static String regexPrefix = "^.*";
private static String regexSuffix = ".*$";
private static boolean verify(List<String> ignoredList, String url) {
for (String regex : ignoredList) {
Pattern pattern = Pattern.compile(regexPrefix + regex + regexSuffix);
Matcher matcher = pattern.matcher(url);
if (matcher.matches()) {
return true;
}
}
return false;
}
复现2,正则匹配绕过
3、修复
package com.****.filter;
import com.alibaba.fastjson.JSON;
import com.*****.entity.result.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 实现登陆拦截器
*/
@Slf4j
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
private static final AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//获取本次请求的URI
String requestURI = request.getRequestURI();
String[] uris = new String[]{
"/register.html",
"/login.html",
"/doc.html",
};
boolean check1 = check(uris, requestURI);
if (check1) {
log.info("check方法被调用,放行");
log.info("拦截的请求 {}",requestURI);
filterChain.doFilter(request, response);
return;
}
if (request.getSession().getAttribute(("user")) != null) {
filterChain.doFilter(request, response);
return;
}
if (request.getSession().getAttribute(("user")) == null) {
//如果未登录,通过输出流方式向客户端响应数据
response.getWriter().write(JSON.toJSONString(R.error( "NOTLOGIN")));
log.error("未登录,拦截页面 {}",requestURI);
}
}
public boolean check(String[] urls, String requestURI) {
for (String url : urls) {
boolean match = ANT_PATH_MATCHER.match(url, requestURI);
if (match){
return true;
}
}
return false;
}
}