Monday, August 1, 2011

Grails Security - XSS Prevention using Html-Codecs

There are so many applications out there that don’t care about Cross-site scripting (XSS) attacks. Try some of your favourite sites. Just type something like
<script type="text/javascript">alert("attack")</script>
into an input field and check if you get such a message:

Grails has a nice feature for fixing this basic XSS issue.
All you need to do is set the default-codec to html in your Config.groovy:
grails.views.default.codec = "html"
Now every expression inside the ${...} syntax gets encoded in your GSPs:
${'<script type="text/javascript">alert("attack")</script>'}
would become
&lt;script type=&quot;text/javascript&quot;&gt;alert(&quot;attack&quot;)&lt;/script&gt;

Beyond that you need to be careful with Tags (e.g. <g:message...>). Output from those Tags are not encoded by the default-codec. It’s up to the Tag’s implementation.

But what’s with the exception of the rule? What if you have some Html output which should not be encoded, but printed like it is? Or what if you have an email-template which is sent as plain text where variables are not allowed to be encoded?
You can do the following to avoid encoding in special cases :

  • Use the syntax <%=expression%> (instead of ${expression})
  • Put <%@page defaultCodec="none"%> on the top of your template. All ${expression} inside this GSP are not encoded

There is still one small criticism regarding the default codec in Grails:

If you generate a new Grails project the default codec is ‘none’. I saw so many projects in my Grails consulting that didn’t change this (because they did not know or just forgot it). To change this afterwards is a pain and leads to increased effort.
I hope in Grails Version 2.0 the default-codec will change to ‘html’.