近期公司的产品做了一次安全审查,发现后端提供的接口有不安全的Http方法漏洞。不安全的HTTP方法一般包括:TRACE、PUT、DELETE、COPY 等。其中最常见的为TRACE方法可以回显服务器收到的请求,主要用于测试或诊断,恶意攻击者可以利用该方法进行跨站跟踪攻击(即XST攻击),从而进行网站钓鱼、盗取管理员cookie等。
原因分析
引起这个问题的原因其实很简单,因为开发人员开发接口的时候偷懒没有指定RequestMapping中的method属性导致的。没有指定method则系统会默认支持除了TRACE之外的其他7中方式,所以,这就是我要重写的RequestMappingHandlerMapping原因。
当然还有其他的方式,比如搜索出所有采用RequestMapping而没有指定method的地方,然后在代码中明确指定method。这种方式思路最简单,但是毕竟人是懒惰的。而且将来代码开发中如果任然有人不指定method,那么这个问题任然会存在。所以我们需要改动一下,框架加载http接口映射关系的逻辑:
在没有指定method的情况下,只支持GET和POST;在明确指定method的情况下,保留指定的method。
为什么重写的是RequestMappingHandlerMapping
首先后端提供的Http请求均是通过RestController和RequestMapping(或者衍生的GetMapping/PostMapping等)来实现的。那在接收http请求之后,如何将http请求映射到具体的Controller中的方法上呢?答案在HandlerMapping这个接口。这个具体映射过程细节以后再说,而HandlerMapping接口的映射方法getHandler是在AbstractHandlerMapping中实现的,而AbstractHandlerMapping的一个非抽象子类就是RequestMappingHandlerMapping。
重写RequestMappingHandlerMapping的哪个方法
从RequestMappingHandlerMapping中的getMappingForMethod方法可以看出,接口的映射信息,是由两部分组成的。一部分是来自于Controller类上的RequestMapping注解,一部分是来自于方法上的RequestMapping注解。所以,在这个方法中createRequestMappingInfo调用了两次,然后再组合。
@Override
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
RequestMappingInfo info = createRequestMappingInfo(method);
if (info != null) {
RequestMappingInfo typeInfo = createR