0

I'm currently working on a Spring MVC project where we are migrating all our jsp files to thymeleaf. I'm aware that the spring form tag has an htmlEscape attribute that will escape user input when rendering, such as when the user submits an invalid form and the user input is rendered bound to the form. An example of this:

 <form:form method="post" id="someForm" modelAttribute="${commandName}" htmlEscape="true" autocomplete="off">
        <div class="form-group">
            <input type="text" id="username" value="<c:out value='${inputValue}'/>"/>
            <input type="password" id="password" />
            <input type="submit" class="btn btn-lg btn-block-sm" value="<spring:message code="header.content.close"/>" tabindex="0" />
            <input type="hidden" name="_eventId" value="continue"/>
        </div>
</form:form>

This fits under the umbrella of output-escaping, which is something that happens on the server side when processing a template to render.

An example of an xss attack this prevents is if the user entered <script>alert("gotcha");</script> for the username, and some arbitrary value for the password. The form will rerender with the entered username bound to the form. The htmlEscape="true" attribute in the form tag will cause this output to be escaped to mitigate xss. So the username field will contain &lt;script&gt;alert(&#034;gotcha&#034;);&lt;/script&gt; when the bound form rerenders with the error, instead of the actually entered valid html

Is there a standard way to achieve this same functionality in thymeleaf?

A few possibilities I see:

  1. This is already built into thymeleaf.

I'm aware that the spring thymeleaf package uses unbescape to perform output escaping on some attributes, for example SpringValueTagProcessor which I believe escapes output on th:value attributes. However, I'm not sure this is equivalent, and fear there may be security holes left unfilled if this was done in a way that only partially mitigates what the spring form htmlEscape fully mitigates.

If so, please explain how this covers the same cases that htmlEscape does.

  1. There is an existing Spring / Spring MVC solution that is flexible enough to not rely on jsp.

If so, what?

  1. There is a common solution to this for thymeleaf which involves some modification of the template parsing engine.

If so, please explain.

Here is a brief article to give you an idea of what I mean regarding the spring form behavior. Regarding this article, it appears that setting the defaultHtmlEscape to false globally in the web.xml only overrides the default value of HtmlEscapeTag, which appears to only work for spring tags. Thus I don't think the solution can be applied to thymeleaf.

I would appreciate any direction here.

Joshua
  • 177
  • 3
  • 3
  • 14
  • See this [GitHub discussion](https://github.com/thymeleaf/thymeleaf/discussions/877) for a complete answer to this. – Joshua Feb 24 '22 at 19:43

2 Answers2

0

Escaping of output text is done automatically if you use th:text. In rare cases, you can use th:utext if you want to use unescaped text, but you have to be aware of the security implications. See Process thymeleaf variable as html code and not text for some more info.

Wim Deblauwe
  • 25,113
  • 20
  • 133
  • 211
  • Thanks for the answer Wim. I'm aware of the differences between *th:text* and *th:utext*, however my question surrounds output escape filtering *on form elements*. For example, a user could enter their username as ** and some invalid password. After submitting, the form would be rendered with an error message and the username bound to the form, which in this simple case comes from *th:value*. I'm aware that *th:value* is output escaped with the unbescape library, but am asking if TL doesn't escape some form elements that spring *htmlEscape* would have? – Joshua Feb 18 '22 at 19:23
0

I ended up getting an answer on the GitHub discussions for the Thymeleaf project here, which I will summarize and clarify:

HTML escaping is built into Thymeleaf form elements by default.

This is evidenced by th:input processor source code. Note the use of getDisplayString which performs html output escaping via org.springframework.web.util.HtmlUtils

I went through and manually checked all the uses of getDisplayString where htmlEscape is false and can verify that in these cases, the output is HTML escaped before displaying (in the case of SpringErrorTagProcessor and SpringUErrorsTagProcessor), they don't output any content to escape (SpringSelectedValueComparator returns a boolean), or the expression is a bound object (SPELVariableExpressionEvaluator).

See GitHub issue thymeleaf/thymeleaf-docs#84 for information regarding the docs being updated accordingly.

Joshua
  • 177
  • 3
  • 3
  • 14