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 >
<input type="text" id="username" value="<c:out value='${inputValue}'/>"/>
<input type="password" id="password" />
<input type="submit" 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 <script>alert("gotcha");</script>
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:
- 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.
- There is an existing Spring / Spring MVC solution that is flexible enough to not rely on jsp.
If so, what?
- 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.
CodePudding user response:
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.
CodePudding user response:
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.