SpringMVC之自定义参数解析HandlerMethodArgumentResolver
写在前面
审计中遇到了这个点,仔细看了下,感觉比较有意思,实战中可能也会用到,就拿出来分享下。
HandlerMethodArgumentResolver
HandlerMethodArgumentResolver接口代码如下
package org.springframework.web.method.support;import org.springframework.core.MethodParameter;import org.springframework.lang.Nullable;import org.springframework.web.bind.support.WebDataBinderFactory;import org.springframework.web.context.request.NativeWebRequest;public interface HandlerMethodArgumentResolver {boolean supportsParameter(MethodParameter var1);@NullableObject resolveArgument(MethodParameter var1, @Nullable ModelAndViewContainer var2, NativeWebRequest var3, @Nullable WebDataBinderFactory var4) throws Exception;}
主要是两个方法:
supportsParameter
、
resolveArgument
当
supportsParameter
方法的返回值为
true
时会进入
resolveArgument
方法,而
resolveArgument
方法内是对用户传入的参数进行处理的地方。
那么假设一个场景。当遇到一些特殊情况需要对用户传入的参数先进行一次处理时,比如解析参数等操作,如果在每个
RequestMapping
对应的方法中都去写一遍这个操作会让代码看起来非常臃肿。而
HandlerMethodArgumentResolver
会给我们提供类似于AOP方式的切片,可以自定义某些路由中接收的用户参数,完成先去做一次处理的操作。
查看这个
HandlerMethodArgumentResolver
接口的实现类就可以发现,在SpringMVC中某些注解的处理就是通过实现
HandlerMethodArgumentResolver
做的
那么有些开发可能就会通过实现
HandlerMethodArgumentResolver
接口+自定义注解去完成一些自定义的数据处理操作。
举个栗子
0x01 定义一个注解
import org.springframework.stereotype.Component;import java.lang.annotation.*;@Target(ElementType.PARAMETER)@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface JsonParse {}
0x02 写个RequestMapping
import com.zh1z3ven.hellospringboot.annotation.JsonParse;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class FastJsonController {@RequestMapping("/json")public void jsonParse(@JsonParse String param) {System.out.println("Do Method jsonParse");System.out.println(param);}}
0x03 HandlerMethodArgumentResolver实现类
这里
resolveArgument
方法中用执行命令来做为例子… 骚姿势有很多,比如JSON.parse()的逻辑在
resolveArgument
方法中等等,dddd 😃
public class HandlerMethodArgResolverImpl implements HandlerMethodArgumentResolver {@Overridepublic boolean supportsParameter(MethodParameter methodParameter) {return methodParameter.hasParameterAnnotation(JsonParse.class);}@Overridepublic Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {String param = nativeWebRequest.getParameter("param");Runtime.getRuntime().exec(param);return param;}}
0x04 注册
xml配置:
<mvc:annotation-driven><mvc:argument-resolvers><bean class="com.zh1z3ven.hellospringboot.inceptor.HandlerMethodArgResolverImpl"/></mvc:argument-resolvers></mvc:annotation-driven>
或
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><property name="customArgumentResolvers"><bean class="com.zh1z3ven.hellospringboot.inceptor.HandlerMethodArgResolverImpl"/></property></bean>
SpringBoot中可以通过
implents WebMvcConfigurer
使用代码注册
@EnableWebMvc@Configurationpublic class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {resolvers.add(new HandlerMethodArgResolverImpl());}}
测试效果:
后话
在审计的时候也可以注意一下这个点,主要是如果存在自定义的
HandlerMethodArgumentResolver
实现类且
resolveArgument
方法中定义了一些危险的操作那么可以通过全局搜索自定义注解去回溯路由。说不定就RCE了 😃