Java安全之freemaker模版注入
freemaker简介
FreeMarker 是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。
模板文件存放在Web服务器上,当访问指定模版文件时, FreeMarker会动态转换模板,用最新的数据内容替换模板中 ${...}
的部分,然后返回渲染结果。
freemaker中的一些概念:
-
${...}
: FreeMarker将会输出真实的值来替换大括号内的表达式,这样的表达式被称为 interpolation (插值) -
FTL 标签(FreeMarker模板的语言标签): FTL标签和HTML标签有一些相似之处,但是它们是FreeMarker的指令,是不会在输出中打印的。 这些标签的名字以
#
开头。(用户自定义的FTL标签则需要使用@
来代替#
,但这属于更高级的话题了。) -
注释:注释和HTML的注释也很相似, 但是它们使用
<#--
and-->
来标识。 不像HTML注释那样,FTL注释不会出现在输出中(不出现在访问者的页面中), 因为 FreeMarker会跳过它们。
其他任何不是FTL标签,插值或注释的内容将被视为静态文本, 这些东西不会被FreeMarker所解析;会被按照原样输出出来。
freemaker中的一些指令: http://freemarker.foofun.cn/dgui_quickstart_template.html
一般漏洞常位于后台可以编辑模版的地方,通过插入恶意的ftl指令到ftl文件中,当后端再次return或者process时即可触发代码执行。
主要代码
Configuration cfg = new Configuration();
cfg.setAPIBuiltinEnabled(true); // 开启api
StringTemplateLoader stringLoader = new StringTemplateLoader();
stringLoader.putTemplate("myTemplate",templateContent);
cfg.setTemplateLoader(stringLoader);
Template template = cfg.getTemplate("myTemplate","utf-8");
Map root = new HashMap();
root.put("data",data);
StringWriter writer = new StringWriter();
template.process(root,writer); //*
return writer.toString();
利用方式
api
这些内建函数从 FreeMarker 2.3.22 版本开始存在。
通过它可以访问底层Java Api Freemarker的 BeanWrappers
。这个内置函数默认不开启,但通过 Configurable.setAPIBuiltinEnabled可以开启它。
如果value本身支持这个额外的特性, value?api
提供访问 value
的