使用Thymeleaf显示已清理HTML的最简洁方法?

时间:2015-08-07 15:57:17

标签: java spring thymeleaf

我的数据库中有一些数据,我们允许输入一个HTML子集以便稍后显示。出于偏执/不信任旧版本的代码,我希望在显示之前通过Jsoup的Jsoup.clean()之类的东西运行它,以防止跨站点脚本(XSS)问题。

此外,我想将"\n"替换为"<br/>",以便为这些字段输入更多自由格式文本的用户可以在以后看到合理的内容。

在我的JSP中,我编写了一个自定义taglib来处理这个问题,我这样用过:

<util:whitelistHtml value="${some.thing}" convertNewlines="true"/>

在Thymeleaf中重建这种行为的最简洁方法是什么?我看到了几个选项:

  • 一个参数化片段,利用Spring表达式调用Jsoup,如th:utext="${T(org.jsoup.Jsoup).clean(some.thing.replaceAll('\n', '<br/>'), T(org.jsoup.safety.Whitelist).basic())}"
  • 自定义方言,我在其中编写新的foo:cleanHtml="${some.thing}"属性处理程序,可能会扩展org.thymeleaf.standard.processor.attr.StandardUtextAttrProcessororg.thymeleaf.standard.processor.attr.AbstractStandardUnescapedTextChildModifierAttrProcessor以执行大部分工作。
  • 我可以使用的一些自定义实用程序对象,例如th:utext="${#cleaners.cleanHtml(${some.thing}, true)}"
  • 在我的控制器中执行此处理,只使用“干净”形式传递额外的模型属性,或者让控制器直接覆盖主模型对象的属性,然后使用th:utext="${some.thing}"

以上哪一项最有可能继续在Thymeleaf 3之后继续工作,并且也会出现意外XSS暴露的风险最小,或者至少使代码比JSP文件更容易进行审计?

1 个答案:

答案 0 :(得分:0)

我发现添加自定义实用程序对象的解决方案相对简单。

这基本上涉及creating a new dialect,并覆盖getAdditionalExpressionObjects以添加新对象的实例:

public class CleanHtmlDialect extends AbstractDialect
        implements IExpressionEnhancingDialect {
    // ...

    @Override
    public Map<String, Object> getAdditionalExpressionObjects(IProcessingContext processingContext) {
        Map<String, Object> expressionObjects = new HashMap<>();
        expressionObjects.put("cleanHtml", new CleanHtml());
        return expressionObjects;
    }
}