Java Freemarker中的默认转义
在Freemarker模板中,我们可以使用escape指令自动将转义应用于包含块内的所有插值:Java Freemarker中的默认转义,java,xss,escaping,freemarker,Java,Xss,Escaping,Freemarker,在Freemarker模板中,我们可以使用escape指令自动将转义应用于包含块内的所有插值: <#escape x as x?html> <#-- name is escaped as html --> Hallo, ${name} </#escape> 你好,${name} 是否有一种方法可以通过编程实现类似的效果,即定义应用于模板中所有插值的默认转义,包括那些在转义指令之外的插值 谢谢。有一个解决方案,尽管它并不完全是琐碎的。您可以创建一个
<#escape x as x?html>
<#-- name is escaped as html -->
Hallo, ${name}
</#escape>
你好,${name}
是否有一种方法可以通过编程实现类似的效果,即定义应用于模板中所有插值的默认转义,包括那些在转义指令之外的插值
谢谢。有一个解决方案,尽管它并不完全是琐碎的。您可以创建一个特殊的TemplateLoader,它包装其他模板加载器,并在模板源文本的序言中注入,并添加作为它的结束语 明显的缺点: -第一行中的列号将被丢弃
-如果模板以声明开头,则需要在其后面插入。详细说明Attila的答案:您可以使用类似的类,然后按如下方式包装模板加载器:
final TemplateLoader templateLoader = new ClassTemplateLoader(this.getClass(), templatePath) {
/**
* Replaces the normal template reader with something that changes the default
* escaping to HTML as to avoid XSS attacks.
*/
@Override
public Reader getReader(Object templateSource, String encoding) throws IOException {
return new WrappingReader(super.getReader(templateSource, encoding), "<#escape x as x?html>", "</#escape>");
}
};
final TemplateLoader TemplateLoader=新类TemplateLoader(this.getClass(),templatePath){
/**
*用更改默认值的内容替换普通模板读取器
*转义为HTML以避免XSS攻击。
*/
@凌驾
公共读取器getReader(对象模板源,字符串编码)引发IOException{
返回新的包装器(super.getReader(templateSource,编码),“”,“”);
}
};
如果在添加的零件中不包含换行符,则不会出现换行编号问题。但是,您不能将/[#ftl]用于这种方法。您实际上不需要包装器来添加转义。您只需在任何TemplateLoader周围创建一个decorator,将模板读入一个字符串,将模板文本包装在转义符中,然后返回一个StringReader来读取结果字符串。看看是怎么做到的。我发现的唯一问题是,如果使用这种方法并从类路径中包含spring.ftl宏,它们会爆炸,因为它们的顶部有一个声明。但是,您可以简单地将spring.ftl复制到模板路径中,并删除声明(以及所有转义指令,因为默认情况下您将转义)。如果您使用在模板中包含例如HTML,则需要对链接中建议的TemplateLoader进行一些调整 此外,您需要复制spring.ftl,并使用您自己的副本,将顶部的指令移除,就像Tom所说的那样 下面的方法很好,虽然有点粗糙(在commons io上使用番石榴)
自2.3.24以来,每个模板都有一个关联的
freemarker.core.OutputFormat
对象,该对象指定是否以及如何转义${…}
(以及{…}
)输出格式是现成的,但您也可以定义自己的格式。默认情况下,当选定的OutputFormat
转义时,您可以像${foo?no_esc}
那样显式阻止转义
有几种方法可以将模板与所需的OutputFormat
相关联。对于HTML和XML转义,建议的方法是将识别标准文件扩展名配置设置设置为true
,然后对HTML使用ftlh
文件扩展名,对XML模板使用ftlx
文件扩展名。您还可以使用template\u configurers
设置,基于任意模板名称(模板路径)模式将OutputFormat
-s与模板关联。最后,您可以全局设置默认输出格式,如configuration.setOutputFormat(HTMLOutputFormat.INSTANCE)
。您还可以将模板顶部的输出格式改写为
,尽管它应该很少使用
相关文档页面:,Peter指向WrappingReader类的链接不再有效。新地点:
@Override
public Reader getReader(Object pTemplateSource, String pEncoding) throws IOException {
Reader tReader = delegate.getReader(pTemplateSource, pEncoding);
try {
String tTemplateText = CharStreams.toString(tReader);
//only include files ending with "ftl", as we may have some parse=false on included html files
if (pTemplateSource.toString().endsWith("ftl")) {
return new StringReader(ESCAPE_PREFIX + tTemplateText + ESCAPE_SUFFIX);
}
return new StringReader(tTemplateText);
} finally {
Closeables.closeQuietly(tReader);
}
}