26

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.

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.

Community
  • 1
  • 1
Havoc P
  • 8,365
  • 1
  • 31
  • 46
  • 2
    Added a bounty. I think a great answer would look like a Play-specific version of https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet showing exactly what to do in code and template, and would also cover JSON templates. – Havoc P Apr 26 '11 at 14:27
  • You could certainly contribute the answer as a patch to the Play docs, as well! – Havoc P Apr 26 '11 at 14:29
  • another useful utility might be "asJavascriptString()" converting to a JS string literal. – Havoc P Apr 26 '11 at 18:12
  • you could try asking this question at http://groups.google.com/group/play-framework, they are usually very responsive... – opensas Apr 27 '11 at 08:11
  • Related: http://stackoverflow.com/questions/10928642/where-is-the-proper-place-to-escape-quotes-in-play-framework – ripper234 Jun 07 '12 at 09:14

2 Answers2

7

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)

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:

Robin
  • 2,616
  • 22
  • 30
6

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().

Codemwnci
  • 54,176
  • 10
  • 96
  • 129
  • I don't understand how ${} or escape() can be used for CSS and attributes. They don't do the right escaping algorithm for those contexts. Also, what about json templates? – Havoc P Apr 26 '11 at 14:25
  • 1
    You don't have to render your CSS from a static file, you can instead point to a View, which renders in CSS format. Therefore you can gain the power/tools of a groovy template. As for attributes, these are just attributes on an HTML element, so you could have some code such as
    div content
    – Codemwnci Apr 26 '11 at 14:36
  • Wouldn't you have to do it sort of like the addSlashes() example on http://www.playframework.org/documentation/1.2/javaextensions ; i.e. ${myValue.someCSSEscapeFunction().raw()} ? Without the .raw() then there would be HTML escaping on top of CSS escaping which would break. And I don't think someCSSEscapeFunction() exists in Play already... – Havoc P Apr 26 '11 at 14:59
  • What would you use for example to do - I think it has to be like ${user.name.escapeAttribute().raw()} but there isn't an escapeAttribute() right? HTML escaping won't work here. – Havoc P Apr 26 '11 at 15:06
  • Yes, you are right with the CSS, that would just do HTML escaping. The .raw() function means that the HTML is NOT escaped. By default, Play automatically escapes HTML, so you would just use ${user.name} – Codemwnci Apr 26 '11 at 15:48
  • But escaping HTML and escaping the value of an attribute on an element are not the same algorithm. ${user.name} in an attribute value is not AFAIK safe to do. Unless ${} were somehow context-aware... That's why the owasp.org link separates the two cases, right? – Havoc P Apr 26 '11 at 17:53
  • from what I read of the spec, I didn't see a differentiation. My understanding was that the content had to be escaped to prevent dangerous injection of code. I thought this would be the same for attributes and other HTML elements. Maybe worth asking a question about what the difference is between the two. – Codemwnci Apr 26 '11 at 18:59