问题
项目使用的springboot是2.5.14。在进行安全测试的过程中,要求只能使用GET/POST方法,所以添加一个过滤器,实现对请求方法的过滤。
@Component
public class MethodFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain)
throws ServletException, IOException {
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST");
// 过滤请求
if (httpServletRequest.getMethod().equals(RequestMethod.GET.name()) || httpServletRequest.getMethod().equals(RequestMethod.POST.name())) {
filterChain.doFilter(httpServletRequest, httpServletResponse);
} else {
httpServletResponse.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
}
}
}
然后在使用Burp进行测试时,拦截当前请求,并将请求方法修改为`TRACE`时,却出现下面的情况:
问题排查
一开始以为是`Access-Control-Allow-Methods`并没有设置成功,但是断点继续排查时,发现在执行`TRACE`请求时,并没有进入该过滤器。
又觉得是否时过滤器顺序的问题,于是修改过滤器的`Order`,仍没有进入该过滤器。
于是只能找个笨方法:
首先在过滤器中断点,找到正常执行过滤器的起点,断点,判断是否会执行:
按照顺序往下进行排查,最终在 CototeAdapter 中发现问题所在:
我目标是返回的header中Allow不能有除GET/POST以外的方法,但是发现 getServletMethods()方法里面无法设置值。查看代码发现,这段逻辑只针对 Trace ,getAllowTrace()方法对应是可以有设置值的方法,便百度找到了相关Connector的配置,默认 allowTrace=false。那么就修改该配置,方便统一处理返回。因为Spingboot内置Tomcat,在application.yml中也没有相关配置,所以找到了配置类的方法:
@Configuration
public class TomcatConfig {
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() {
return customizer -> customizer.addConnectorCustomizers(connector -> {
connector.setAllowTrace(true);
});
}
}
最终,只是解决了405问题,实际还是没有经过过滤器,请求返回302;
可以继续按照这种方式进行排查。