Beetl模板引擎表达式注入漏洞CVE-2026-52439
Beetl 是一款国产高性能面向 Java 开源模板引擎,主打易学、高性能、功能完备,可用于页面渲染、代码生成、SQL 脚本编写等场景。
一、基本情况
Beetl 语法脱离 Java 原生写法,借鉴现代脚本语言,相比 JSP、Freemarker 门槛更低,内置 if、for、变量赋值、函数调用等基础语法。

Beetl 国内文档完善、中文友好,社区适配国内开发习惯;Freemarker 语法繁琐、Velocity 停止维护,是 Java 轻量模板常用替代方案。
栋科技漏洞库关注到 Beetl 模板引擎中存在表达式注入漏洞,该漏洞现在已经被追踪为CVE-2026-52439,漏洞的CVSS 3.X评分未知。
二、漏洞分析
CVE-2026-52439是Beetl在3.20.2及之前版本中在默认NATIVE_CALL=false安全配置表达式注入风险,可造成远程代码执行(RCE)。
简单来说,目前最新版Beetl模板引擎在配置 NATIVE_CALL = false 的安全限制下仍存在远程代码执行漏洞。
漏洞源于其内置 type.new 函数允许按类名实例化任意类,而属性赋值与取值机制会通过 Java 内省自动调用 setter/getter,
两条路径组合后在 NATIVE_CALL=false 默认配置下仍可触发任意代码执行。
攻击者可利用内置函数 type.new 结合属性赋值/访问时触发的setter/getter方法调用,绕过安全限制实现任意代码执行。
Beetl模板引擎提供安全配置项 NATIVE_CALL(3.17版本后默认为 false)用于禁止任意Java方法调用。
然而,存在两个可链接利用的特性可绕过此保护:
任意类实例化:内置函数 type.new 允许实例化任意类,即使 NATIVE_CALL = false 也无限制。
隐式方法调用:Beetl的属性赋值和访问机制内部使用Java内省机制调用setter和getter方法,绕过了 NATIVE_CALL 限制。
攻击者通过组合这两个特性可:
使用 type.new 创建任意类的实例
通过属性赋值调用setter方法(如 object.property = value)
通过属性访问触发getter方法(如 ${object.property})
这创造了类似FastJSON反序列化漏洞的攻击面,无需显式调用Java方法即可实现任意代码执行,具体情况如下:
com.ibeetl:beetl 通过 beetl-default.properties 中的 FN.type.new=org.beetl.ext.fn.TypeNewFunction 注册内置函数 TypeNewFunction,
该函数在 call(Object[], Context) 中直接以 ctx.gt.getClassSearch().getClassByName(clsName) 加载攻击者传入的类名,
并执行 cls.newInstance(),完全未读取 Configuration.NATIVE_CALL 标志;
当属性赋值/取值被触发时,ReflectBeanAA 与 ObjectUtil 会按 PropertyDescriptor 查找同名 setter/getter,
对刚创建的实例调用任意 setter 与 getter,从而触发 UnpooledDataSource.getConnection() 加载 BCEL 字节码,
或触发 JdbcRowSetImpl.getDatabaseMetaData() 发起 JNDI 反向连接,实现远程代码执行。
三、POC概念验证
(一)测试环境
Beetl模板引擎,配置 NATIVE_CALL = false
Java环境,包含 com.sun.org.apache.bcel.internal.util.ClassLoader(Java 8)
MyBatis依赖(提供 org.apache.ibatis.datasource.unpooled.UnpooledDataSource 类)
(二)利用Payload
payload1 加载恶意bcel字节码实现RCE
管理员已设置登录后刷新可查看
管理员已设置登录后刷新可查看(三)攻击步骤说明 payload1
通过 type.new 创建 UnpooledDataSource 实例
通过 type.new 创建 BCEL ClassLoader 实例
设置 driverClassLoader 属性(内部调用 setDriverClassLoader() 方法)
设置 driver 属性为恶意BCEL字节码(内部调用 setDriver() 方法)
访问 connection 属性(内部调用 getConnection() 方法)
getConnection() 触发类加载,通过BCEL ClassLoader加载并执行任意代码
四、影响范围
Beetl <= 3.20.2 模板引擎(所有支持 type.new 功能的版本)
五、修复建议
在默认 NATIVE_CALL = false 安全配置下禁用type.new,或提供type.new可实例化白名单防御
六、参考链接
管理员已设置登录后刷新可查看