David Balažic opened SPR-14787 and commented
The spring:EscapeBody tag with the attributes htmlEscape="true" javaScriptEscape="true" first does a HTML escape on the body and then a JavaScript escape.
Is it possible to reverse the order of the operations? Maybe a new attribute or similar.
Affects: 4.3.3
Comment From: spring-projects-issues
Brian Clozel commented
Could you explain a bit the rationale behind this issue? Is there a specific order that should be enforced for security reasons?
I'm just trying to find out if the order you're proposing should be the default after all.
Comment From: spring-projects-issues
David Balažic commented
Sometimes one need the one, sometimes the other. Now the second option is not available (unless nesting the tags would work, haven't checked),
I'm not saying the default should be changed.
The opposite of current order seems good in what I see a more common case: encode some free text to Javascript string, then encode the result to be able to embed it into a HTML document.
Comment From: spring-projects-issues
David Balažic commented
See here for an example where this would be needed: http://stackoverflow.com/questions/39861628/in-jsp-how-to-escape-a-string-value-for-javascript-first-then-for-html
Comment From: spring-projects-issues
Bulk closing outdated, unresolved issues. Please, reopen if still relevant.
Comment From: xerces8
I checked the current sources at https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EscapeBodyTag.java (at version 5.1.5 it seems) and this seems still relevant.
Consider the following code:
<a onclick='alert("${needescape}");'>Foo</a>
If <s:escapeBody htmlEscape="true" javaScriptEscape="true">
is used, and the string value a<b"x
, then it is first HTML escaped to a<b"x
and then JS escaped to the same, as those characters do not need escaping for JS.
So the result is:
JSP source:
<c:set var="needescape" >a<b'x</c:set>
<a onclick='alert("<s:escapeBody htmlEscape="true" javaScriptEscape="true">${needescape}<s:escapeBody>");'>Foo</a>
Generated HTML:
<a onclick='alert("a<b"x");'>Foo</a>
Which when evaluated for the attribute onclick, gives the value alert("a<b"x");
which is invalid JavaScript.
When clicking that A element in the browser, it breaks with this message in the error console:
SyntaxError: missing ) after argument list[Learn More] examplePage:1:11
So in this use case, escaping JS first, and then HTML second would be needed.
Comment From: meeque
@xerces8 I've run into the same problem just today.
It would be great to document the escape order. According to the source code it's:
- html encode
- JS encode
But sadly that's documented nowhere. Do you think it's worthwhile to open a new issue to fix the documentation?
Btw, I'm ok with this issue getting closed without a solution. People who need a different order should invoke escapeBody (or similar) multiple times for the order that the need. But documentation would be great!