1.<#escape>指令html
2.<xxx?html>内建函数java
方法1、spring
网上比较多的是经过TemplateLoader,给加载的template文件2头套<#escape>api
<#escape x as x?html> your template code </#escape>
参考: http://techdiary.peterbecker.de/2009/02/defending-against-xss-attacks-in.html缓存
可是如今咱们应用的对freemarker作了扩展,一个页面分3个部分,一个layout、一个view、多个control。框架
屡次render才到最终结果。要控制比较麻烦配置,也不友好。xss
改源码的$变量、默认所有转义、对固定的扩展的layout、一个view、多个control,配置正则原义输出。函数
变量是string类型的时候,用了xxx?string做为原义输出的内建函数。ui
缺点:比较暴力,修改了DollarViable源码,后续freemarker有升级要跟随修改url
/** * The original code * env.getOut().write(escapedExpression.getStringValue(env)); */ String expr = escapedExpression.getCanonicalForm(); TemplateModel referentModel = escapedExpression.getAsTemplateModel(env); String output = Expression.getStringValue(referentModel, escapedExpression, env); if (referentModel instanceof TemplateScalarModel) { // layout placeholder and widget no escape and ?string if (expr.indexOf("!noescape") > -1 || expr.indexOf("?html") > -1 || expr.indexOf("parameters.") > -1 || expr.endsWith("?string") || doNoEscape(expr, env)) { env.getOut().write(output); } else { env.getOut().write(freemarker.template.utility.StringUtil.HTMLEnc(output)); } }else{ env.getOut().write(output); }
<!-- 设置 ViewResolver --> <bean id="freemarkerConfiguration" class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean"> <property name="templateLoaderPath" value="file://${xxxxxx.template.templatePath}" /> <property name="freemarkerSettings"> <props> <prop key="default_encoding">UTF-8</prop> <prop key="number_format">#</prop> <!-- 配置缓存时间 --> <prop key="template_update_delay">${xxxxxxx.template.update.delay}</prop> <prop key="classic_compatible">true</prop> <prop key="auto_import">/macro/macros.ftl as spring</prop> <prop key="url_escaping_charset">UTF-8</prop> <prop key="defaultEncoding">UTF-8</prop> <prop key="boolean_format">true,false</prop> <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop> <prop key="date_format">yyyy-MM-dd</prop> <prop key="locale">zh_CN</prop> </props> </property> <property name="freemarkerVariables"> <map> <entry key="noescape_patterns" value-ref="noescape_patterns"/> </map> </property> </bean> <!-- 不进行转义正则 --> <util:list id="noescape_patterns" list-class="java.util.ArrayList"> <bean class="java.util.regex.Pattern"> <constructor-arg value="(^placeholder$)|(^widget)|(^token\(\)$)" /> <constructor-arg value="0"/> </bean> </util:list>