Spring视图操作

视图概述

考虑一个使用Thymeleaf作为其模板引擎的简单Spring应用程序:

@Controller
public class HelloController {

    @GetMapping("/")
    public String index(Model model) {
        model.addAttribute("message", "happy birthday");
        return "welcome";
    }
}

index方法将为根URL / 的每个GET请求调用。它没有参数并返回静态字符串welcome。Spring将welcome解释为View的名称,并尝试找到位于应用程序资源中的resources/templates/welcome.html文件。如果Spring找到它,将从模板文件渲染视图并返回给用户。

不受信任的Thymeleaf视图名称

如果使用Thymeleaf视图引擎(Spring中最流行的),模板可能如下所示:

<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<div th:fragment="header">
    <h3>Spring Boot Web Thymeleaf Example</h3>
</div>
<div th:fragment="main">
    <span th:text="'Hello, ' + ${message}"></span>
</div>
</html>

Thymeleaf引擎支持文件布局,允许您通过使用<div th:fragment="main">在模板中指定片段,然后仅从视图中请求此片段:

Thymeleaf足够智能,只从welcome视图返回主要的div,而不是整个文档。

在从文件系统加载模板之前,Spring ThymeleafView类将模板名称解析为表达式:

因此,如果模板名称或片段与不受信任的数据连接,它可能导致表达式语言注入,从而导致RCE。

例如,以下方法容易受到表达式语言注入攻击:

以下请求在服务器上创建executed文件:

此漏洞利用使用表达式预处理。为了使表达式被Thymeleaf执行,无论前缀或后缀是什么,都需要用__${}__::.x包围它。

不受信任的隐式视图名称

控制器并不总是返回明确告诉Spring使用什么视图名称的字符串。如文档中所述,对于某些返回类型,如voidjava.util.Maporg.springframework.ui.Model,视图名称通过RequestToViewNameTranslator隐式确定。

这意味着乍一看这样的控制器可能看起来完全无害,它几乎什么都不做,但由于Spring不知道要使用什么视图名称,它从请求URI中获取

具体来说,DefaultRequestToViewNameTranslator执行以下操作:

所以,它变得易受攻击,因为用户控制的数据(URI)直接进入视图名称并被解析为表达式:

参考

最后更新于