Spring 视图操纵漏洞( 二 )
文章插图
当解析到 ThymeleafViewResolver 这个方法的时候 , 会进入createView , 在这个方法中根据几个条件进行判断 , 比如redirect:或者forward:等等 。 因此我们的ViewName 不满足 , 自然是在resolveViewName处理之后返回了ThymeleafView。
文章插图
同理在 UrlBasedViewResolver# createView方法当中也是大概根据redirect:或者forward:进行判断 , 因此在 resolveViewName处理之后返回了InternalResourceView。
文章插图
再看 getBestView , 我们当前的candidateViews 这个list 当中有两个view分别是InternalResourceView和ThymeleafView , 进入处理之后返回的是 ThymeleafView 。 也就是说经过view = resolveViewName(viewName, mv.getModelInternal, locale, request);处理之后 , 返回了我们的视图方法是ThymeleafView , 紧接着就是view.render(mv.getModelInternal, request, response);来到相关的视图方法中进行解析了 。
文章插图
当然最后的模版解析过程在 org.thymeleaf.spring5.expression.SPELVariableExpressionEvaluator# evaluate 。
exec:347, Runtime (java.lang)
...
evaluate:263, SPELVariableExpressionEvaluator (org.thymeleaf.spring5.expression)
executeVariableExpression:166, VariableExpression (org.thymeleaf.standard.expression)
executeSimple:66, SimpleExpression (org.thymeleaf.standard.expression)
execute:109, Expression (org.thymeleaf.standard.expression)
execute:138, Expression (org.thymeleaf.standard.expression)
preprocess:91, StandardExpressionPreprocessor (org.thymeleaf.standard.expression)
parseExpression:120, StandardExpressionParser (org.thymeleaf.standard.expression)
parseExpression:62, StandardExpressionParser (org.thymeleaf.standard.expression)
parseExpression:44, StandardExpressionParser (org.thymeleaf.standard.expression)
renderFragment:278, ThymeleafView (org.thymeleaf.spring5.view)
render:189, ThymeleafView (org.thymeleaf.spring5.view)
No.3
区分
1、加上@ResponseBody注释
//GET /fragment?section=main
//GET /fragment?section=__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime.exec(%22touch%20executed%22).getInputStream).next%7d__::.x
@GetMapping("/fragment")
public String fragment(@RequestParam String section) {
return "welcome :: " + section; //fragment is tainted
}
@GetMapping("/safe/fragment")
@ResponseBody
public String safeFragment(@RequestParam String section) {
return "welcome :: " + section; //FP, as @ResponseBody annotation tells Spring to process the return values as body, instead of view name
}
首先需要了解 @ResponseBody 注释的作用 。
1、该注解用于读取Request请求的body部分数据 , 使用系统默认配置的HttpMessageConverter进行解析 , 然后把相应的数据绑定到要返回的对象上;
2、再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上 。
而实际上在 RequestMappingHandlerAdapter# handleInternal 返回view的对象的时候返回空 , 找不到模版对象 , 自然也就没有下面的模版解析render 的渲染过程了 。
文章插图
2、redirect:或者forward:前缀
@GetMapping("/safe/redirect")
public String redirect(@RequestParam String url) {
return "redirect:" + url; //FP as redirects are not resolved as expressions
}
@GetMapping("/safe/forward")
public String forward(@RequestParam String url) {
return "forward:" + url; //FP as redirects are not resolved as expressions
}
实际上我们前面也聊过了在 AbstractCachingViewResolver# resolveViewName 当中 , 当调用view = createView(viewName, locale);会进入每个模版的 createView方法 , 而这个方法根据前缀redirect:或者forward:进行匹配 , 返回的是RedirectView或者 InternalResourceView , 所以自然不会进行模版解析 。
文章插图
文章插图
3、HttpServletResponse标记
在构造方法中指定HttpServletResponse response的org/springframework/web/servlet/DispatcherServlet# doDispatch 方法之后 , 实际上就不返回 modelandView, 也就是说实际上没有进行模版解析 。
- Spring security CSRF 跨域访问限制问题
- Spring Boot搭建的一个在线文件预览系统
- 面试官:问你一个,Spring事务是如何传播的?
- 对Spring MVC接口进行Mock测试
- Spring Cloud Alibaba之 Sentinel
- SpringBoot+MyBatis+MySQL读写分离实现
- SpringBoot构造流程源码分析:Web应用类型推断
- 搭建私有Sentry日志收集系统并集成到springboot
- Spring事务原理?事务在方法间如何传播?为什么会失效?
- SpringBoot扫描不到组件?给你提供几种方案