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>