安全攻防
morning
Solon框架模板漏洞深度剖析与修复实战
2026-05-08
1 阅读
蚁景网安实验室
前言 分析发现 Solon 框架在3.1.0版本上存在一个有意思的模板漏洞,对这个漏洞进行简单分析后,发现整个漏洞的利用链是非常有意思的。同时发现最新版的修复方式过于简单,询问 AI 后,AI 也认为修复也是不完善的安全修复,于是进行一系列的绕过尝试,最后还是没有利用成功,简单进行分享。 环境搭建 Solon 框架简介 Solon 是一个轻量级的 Java 应用开发框架,类似于 Spring Boot ,但更加轻量。支持多种模板引擎,包括 Beetl、FreeMarker、Velocity 等。在模板处理方面,Solon 采用了灵活的渲染器映射机制,也是出现这个漏洞的关键原因。 测试环境搭建 https://solon.noear.org/start/build.do?artifact=helloworld_jdk8&project=maven&javaVer=1.8 可以下载 solon 的项目模板 并进行修改 修改一下 pom.xml 文件 设置 solon 的版本为 3.1.0 将原本的视图插件 solon-view-freemarker 替换为以下的任意一种 < dependency > < groupId > org . noear < /groupId> < artifactId > solon - view - enjoy < /artifactId> < /dependency> < dependency > < groupId > org . noear < /groupId> < artifactId > solon - view - beetl < /artifactId> < /dependency> < dependency > < groupId > org . noear < /groupId> < artifactId > solon - view - thymeleaf < /artifactId> < /dependency> < dependency > < groupId > org . noear < /groupId> < artifactId > solon - view - velocity < /artifactId> < /dependency> 在 DemoController.java 中 添加代码 并启动运行 @ Mapping ( "/templates" ) public ModelAndView templates ( Context ctx ) throws IOException { ModelAndView modelAndView = new ModelAndView ( ctx . param ( "templates" )); return modelAndView ; } 漏洞验证与分析 漏洞验证 我们选用视图插件solon-view-velocity,不同的视图插件对跨目录的处理有所不同,之后会对此进行详细解释 < dependency > < groupId > org . noear < /groupId> < artifactId > solon - view - velocity < /artifactId> < /dependency> 可以看到传入的参数通过 ../ 实现了跨目录的文件读取并将内容解析到页面上 核心调用链分析 通过调试对这个漏洞进行分析 遇到这种情况有一个小的 tips 我们可以通过尝试加载一个不存在的文件,这样 idea 的控制台中会输出相对详细的调用链,方便我们下断点进行调试分析。 org.noear.solon.core.handle.RenderManager#render 这里会根据文件后缀来选择视图插件,如果没有匹配的就选择用默认渲染器来处理 org.noear.solon.view.velocity.VelocityRender#render org.noear.solon.view.velocity.VelocityRender#render_mav org.apache.velocity.runtime.RuntimeInstance#getTemplate(java.lang.String, java.lang.String) org.apache.velocity.runtime.resource.ResourceManagerImpl#getResource 整体流程顺下来应该是 用户输入 → Context.param() → ModelAndView() → RenderManager.render()→ 模板引擎处理 在模板引擎处理之前没有对模板文件的路径进行处理和限制,这样一来如果