HTML模板引擎中的默认占位符文本是HTML-escape,这有助于防止XSS(跨站点脚本)攻击。是否可以在StringTemplate中实现此行为?
我尝试注册自定义AttributeRenderer
,除非format
为"raw"
,否则会转义HTML:
stg.registerRenderer(String.class, new AttributeRenderer() {
@Override
public String toString(Object o, String format, Locale locale) {
String s = (String)o;
return Objects.equals(format, "raw") ? s : StringEscapeUtils.escapeHtml4(s);
}
});
但它失败了,因为在这种情况下,StringTemlate不仅会转义占位符文本,还会转义模板文本本身。例如这个模板:
example(title, content) ::= <<
<html>
<head>
<title>$title$</title>
</head>
<body>
$content; format = "raw"$
</body>
</html>
>>
呈现为:
<html>
<head>
<title>Example Title</title>
</head>
<body>
<p>Not escaped because of <code>format = "raw"</code>.</p>
</body>
</html>
有人可以帮忙吗?
答案 0 :(得分:1)
默认编码没有好的解决方案。模板通过AttributeRenderer传递给字符串数据类型,并且没有上下文信息来检测它是否正在处理模板或变量。因此,所有字符串(包括模板)都是默认编码的,因为您无法为模板指定“raw”。
另一种解决方案是在需要编码的变量中使用format="xml-encode"
。内置StringRenderer
支持多种格式:
所以你的例子是:
example(title, content) ::= <<
<html>
<head>
<title>$title; format="xml-encode"$</title>
</head>
<body>
$content$
</body>
</html>
>>
为了默认编码 ,您的选项有限。替代方案是:
String
),因此您可以为自定义数据类型注册HtmlEscapeStringRenderer
。如果将复杂对象用作已使用标准字符串的变量,则很难。title
(转义)和title_raw
(原始)。在这种情况下,您不需要自定义AttributeRenderer。 StringTemplate具有严格的视图/模型分离,您需要在使用原始值和转义值呈现模型之前填充模型。这两个选项都不是特别理想,但我没有看到StringTemplate4的任何其他选项。
答案 1 :(得分:0)
答案是恢复为StringTemplate v3。