Как отобразить HTML в сообщениях об ошибках Grails без потери кодировки для предоставленного пользователем содержимого? - PullRequest
0 голосов
/ 12 декабря 2011

Мне нужно отобразить некоторый HTML в сообщениях об ошибках Grails, чтобы пометить некоторый контент для внешней системы, на которую я не могу влиять. Это просто несколько простых тегов span с атрибутом class = "notranslate". По умолчанию HTML будет экранирован, поэтому я отключил кодек в теге, что приводит к другой проблеме:

Теперь все, что вводит пользователь, будет отображаться в HTML страницы, что позволяет легко XSS ... Мое решение на данный момент состоит в том, чтобы отключить только кодек HTML для этой страницы и использовать пользовательские сообщения об ошибках, которые не включают в себя то, что ввел пользователь, но которые мне кажутся довольно неуклюжими.

Я также видел, что может быть возможность возиться с MessageSource, но я не люблю переходить на многое в недрах Грааля. У меня была еще одна идея - создать собственный фильтр, который пропускает только тот HTML-код, который я одобряю. Я также отказался от этой идеи, мне казалось, что я решил проблему на неправильном уровне абстракции.

Есть идеи, как решить эту проблему?

TL; DR Мне нужно обернуть переменные части сообщения об ошибке в тегах.

Ответы [ 2 ]

3 голосов
/ 30 августа 2012

Чтобы не получить флэш-сообщение об ошибке в кодировке 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 голос
/ 13 декабря 2011

У меня есть идея с оберткой 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.

Три амперсанда - это дикий символ. Затем создайте taglib, который переносит g:message следующим образом:

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>

Этот код непроверен, поэтому он может пропустить некоторые детали в регулярном выражении, но я надеюсь, что вы поняли.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...