如何在Grails错误消息中显示HTML而不会丢失用户提供的内容的编码?

时间:2011-12-12 17:15:45

标签: html validation grails

我需要在Grails错误消息中显示一些HTML,以标记我无法影响的外部系统的某些内容。它只是一些简单的span标签,带有class =“notranslate”属性。默认情况下,HTML将被转义,因此我禁用了标记中的编解码器,这导致了另一个问题:

现在用户输入的所有内容都将显示在页面的HTML中,这样可以轻松实现XSS ... 我现在的解决方案是仅禁用此页面的HTML编解码器,并使用自定义错误消息,这些消息不包括用户输入的内容,但这对我来说似乎相当笨拙。

我也看到可能有可能摆弄MessageSource,但我不喜欢在Grails的内容中改变很多。我的另一个想法是创建一个自定义过滤器,它只允许我批准的HTML。我也放弃了这个想法,感觉我在错误的抽象层面上处理问题。

任何想法如何解决这个问题?

TL; DR 我需要在标记中包含错误消息的可变部分。

2 个答案:

答案 0 :(得分:3)

为了不获取HTML编码的错误消息,可以使用以下内容:

<g:hasErrors bean="${editingInstance}">
    <div class="errors">
        <g:renderErrors bean="${editingInstance}" codec="none"/>
    </div>
</g:hasErrors>

'codec'属性将在ValidationTagLib.groovy中使用:

Closure renderErrors = { attrs, body ->
    def renderAs = attrs.remove('as')
    if (!renderAs) renderAs = 'list'

    if (renderAs == 'list') {
        def codec = attrs.codec ?: 'HTML'
        if (codec == 'none') codec = ''

        [...]
    }
    [...]
}

答案 1 :(得分:1)

我对taglib包装器有所了解。从这开始:

<g:hasErrors bean="${user}">
  <ul>
   <g:eachError var="err" bean="${user}">
       <li><g:message error="${err}" /></li> 
   </g:eachError>
  </ul>
</g:hasErrors>

然后在messages.properties中创建带有一些特殊通配符的消息,如下所示:

user.username.size.toosmall=Username you provided @@@{0}@@@ is too small.

三个&符号是一个荒野。然后创建一个包裹g:message的taglib,如下所示:

class MyTagLib {
    def spanErrorMessage = { attrs, body ->
        out << message(error: attrs.error).replaceAll(/@@@.*@@@/, "<span class='notranslate'>\\1</span>")
    }
}

它会将@@@@@@之间的所有内容替换为您需要的范围。请注意,这些@@@不会在HTML中转义。像这样使用这个taglib:

<g:hasErrors bean="${user}">
  <ul>
   <g:eachError var="err" bean="${user}">
       <li><g:spanErrorMessage error="${err}" /></li> 
   </g:eachError>
  </ul>
</g:hasErrors>

此代码未经测试,从头开始,因此它可能会错过正则表达式中的一些细节,但我希望您能理解。