I'm trying to map out how the Play framework supports escaping.
This is a nice page spelling out the needed functionality:
https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet
So I'm trying to relate that to Play template features and fully understand what Play does and doesn't do.
- HTML escaping:
${}
or the escape()
function
- Attribute escaping: I can't find a built-in solution
- JavaScript escaping: there's an
escapeJavaScript()
http://www.playframework.org/documentation/1.2/javaextensions
- CSS escaping: I can't find a built-in solution
- URL escaping: nothing special built-in, but usual Java solution e.g. Java equivalent to JavaScript's encodeURIComponent that produces identical output? - Update: there's urlEncode() at http://www.playframework.org/documentation/1.2/javaextensions
Another point of confusion is the support for index.json
(i.e. using templates to build JSON instead of HTML). Does ${}
magically switch to JavaScript escaping in a JSON document, or does it still escape HTML, so everything in a JSON template has to have an explicit escapeJavaScript()
?
There's also an addSlashes() on http://www.playframework.org/documentation/1.2/javaextensions , but it doesn't seem quite right for any of the situations I can think of. (?)
It would be great to have a thorough guide on how to do all the flavors of escaping in Play. It looks to me like the answer is "roll your own" in several cases but maybe I'm missing what's included.
I've been looking into this so decided to write up my own answer based on what you already had, this OWASP cheat sheet and some experimentation of my own
HTML escaping:
- ${} or the escape() function
Attribute escaping: (common attributes)
- This is handled in play so long as you wrap your attributes in double quotes (") and use ${}.
- For complex attributes (href/src/etc.) see JavaScript below
- Example unsafe code
<a id=${data.value} href="...">...</a>
<a id='${data.value}' href="...">...</a>
- This would break with this for data.value:
% href=javascript:alert('XSS')
%' href=javascript:alert(window.location)
JavaScript escaping: (and complex attributes)
- Use escapeJavaScript(). http://www.playframework.org/documentation/1.2/javaextensions
- Example unsafe code
<a onmouseover="x='${data.value}'; ..." href="...">...</a>
- This would break with this for data.value:
'; javascript:alert(window.location);//
CSS escaping:
- Not sure as I've no need for this.
- I'd imagine you'd need to create your own somehow. Hopefully there is something out there to manipulate the strings for you.
URL escaping:
- use urlEncode(). http://www.playframework.org/documentation/1.2/javaextensions
I think you are absolutely correct in your summary. Play gives you some of the solutions, but not all. However, in the two places where Play does not offer something (in the CSS and attribute), I cant actually find a need for it.
The OWASP standard specifies that you should escape untrusted code. So, the only way you would have untrusted code in your CSS is if it is being generated dynamically. If it is being generated dynamically, then there is nothing stopping you doing so using standard Groovy templates, and therefore using ${}
and escape()
.
As for the attribute escaping, again, the only time you are going to need this as far as I can tell, is when you are building your view in the groovy templates, so again, you can use ${}
or escape()
.