Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Freemarker中的默认转义_Java_Xss_Escaping_Freemarker - Fatal编程技术网

Java Freemarker中的默认转义

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} 是否有一种方法可以通过编程实现类似的效果,即定义应用于模板中所有插值的默认转义,包括那些在转义指令之外的插值 谢谢。有一个解决方案,尽管它并不完全是琐碎的。您可以创建一个

在Freemarker模板中,我们可以使用escape指令自动将转义应用于包含块内的所有插值:

<#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);  
   }  
}