Spring View Name Manipulation Exploit (Thymeleaf SSTI)
Spring View Name Manipulation Exploit
1
2
3
4
5
6
7
8
9
@Controller
public class HelloController {
@GetMapping("/")
public String index(Model model) {
model.addAttribute("message", "happy birthday");
return "welcome";
}
}
위와 같은 코드가 있다고 가정할 때, 위의 코드에서 @Controller
와 @GetMapping("/")
annotation이 있는데, 이를 통해 “/”로의 매 HTTP 요청마다 메소드가 호출될 것이다.
루트 url은 어떠한 매개변수도 받지 않으며, 단순히 “welcome”을 리턴할 뿐이다.
Spring Framework는 “welcome”을 View Name으로 해석을 하여, resources/templates/welcome.html
을 찾으려 할 것이다.
찾았다면, 렌더링한 후 클라이언트에게 보내준다.
1
2
3
4
@GetMapping("/path")
public String path(@RequestParam String lang) {
return "user/" + lang + "/welcome"; //template path is tainted
}
위에서 리턴 값은 View Name으로 해석된다고 했다.
그럼 user/{lang}/welcome
이라는 파일을 resources/template
같은 템플릿이 들어있는 경로 내에서 찾게 될 것이다.
그러나 파일 시스템에서 템플릿을 렌더링 하기 전에 아래와 같은 코드를 거친다고 하는데, 여기서 취약점이 발생한다.
1
2
3
4
try {
// By parsing it as a standard expression, we might profit from the expression cache
fragmentExpression = (FragmentExpression) parser.parseExpression(context, "~{" + viewTemplateName + "}");
}
리턴 값인 View Name이 바로 viewTemplateName
값이 되는데, 코드를 보면 ~{}
로 감싸져 있다.
만약 리턴 값에 다른 Thymeleaf expression (e.g ${}
가 포함되어 있다면 ~{ ${} }
가 되어 ${7*7}
같은 값이 49로 처리가 되어 리턴이 되는데, 이러한 파일은 경로에 없으므로 에러가 발생하게 된다.
에러가 발생하면 페이지를 보여주는 등 하게 되는데, 그 에러 페이지에 에러 문구로 값이 출력이 되어있으므로 SSTI 취약점이 발생하는 것이다.
기본 Payload로 ${T(java.lang.Runtime).getRuntime().exec('calc')
등이 있다.
참고 자료
- Link
- github.com/veracode-research/spring-view-manipulation
- pulsesecurity.co.nz/articles/EL-Injection-WAF-Bypass