本文转载自:http://www.yshjava.cn/post/333.html
FreeMarker作为"通用"模版引擎, 默认情况下不会对model中的值进行html转义, 然而在web项目中, 为了防止跨站脚本攻击等问题, 必须在对model中的值进行转义.
解决办法:
方法1. 是使用 ${x?html} 可以用于对单个值的转义
方法2. 使用<#escape x as x?html> ... </#escape> 将需要转义的html代码包起来, 这样其中所有的值都会被转义了.
毫无疑问这两个方法都需要大量的重复操作, 如果我所有的模板都需要转义, 有没有一劳永逸的办法呢?
方法3. 使用自定义TemplateLoader
首先我们需要实现一个TemplateLoader. 代码如下:
public class HtmlTemplateLoader implements TemplateLoader {
private static final String HTML_ESCAPE_PREFIX= "<#escape x as x?html>";
private static final String HTML_ESCAPE_SUFFIX = "</#escape>";
private final TemplateLoader delegate;
public HtmlTemplateLoader(TemplateLoader delegate) {
this.delegate = delegate;
}
@Override
public Object findTemplateSource(String name) throws IOException {
return delegate.findTemplateSource(name);
}
@Override
public long getLastModified(Object templateSource) {
return delegate.getLastModified(templateSource);
}
@Override
public Reader getReader(Object templateSource, String encoding) throws IOException {
Reader reader = delegate.getReader(templateSource, encoding);
String templateText = IOUtils.toString(reader);
return new StringReader(HTML_ESCAPE_PREFIX+templateText + HTML_ESCAPE_SUFFIX);
}
@Override
public void closeTemplateSource(Object templateSource) throws IOException {
delegate.closeTemplateSource(templateSource);
}
}
为了和SpringMVC结合起来使用呢, 我们还需要自定义一个FreeMarkerConfigurer
public class CustomFreeMarkerConfigurer extends FreeMarkerConfigurer{
@Override
protected TemplateLoader getAggregateTemplateLoader(List<TemplateLoader> templateLoaders) {
return new HtmlTemplateLoader(super.getAggregateTemplateLoader(templateLoaders));
}
}
然后在spring的xml配置中, 使用它来代替默认的FreeMarkerConfigurer即可
<bean id="freemarkerConfigurer" class="cn.ysh.studio.freemarker.SimpleFreeMarkerConfigurer"> <!-- 其他配置跟之前相同 --> </bean>
当然,如果你觉得使用<#escape>标签不舒服的话,那么也可以自己对html字符串进行转义。HTML中的转义字符的数量不多,如下代码可以将带有跨站脚本攻击风险的html字符转义为安全字符(仅供参考):
String html = "8888</title><body><script type='text/javascript'>alert(\"跨站脚本\");</script>";
html = html.replace("'", "'");//替换单引号
html = html.replaceAll("&", "&");//替换&
html = html.replace("\"", """); // 替换双引号
html = html.replace("\t", " ");// 替换跳格
html = html.replace(" ", " ");// 替换空格
html = html.replace("<", "<");//替换左尖括号
html = html.replaceAll(">", ">");//替换右尖括号
本文转载自http://www.cnblogs.com/nixil/archive/2012/04/23/2466364.html,并稍作修改!