JSON is insecure - how you can deal with that with Struts 2 and jQuery

von

Recently I have learned on the Struts 2 mailinglist how insecure JSON actually is. One approach to get rid of this risk is to put any JSON responses into comments like this:

/* {"key":"value"} */

Of course, this not valid JSON. The JSON protocol does not support comments itself. This leads to problems with tools like jQuery. In the next Struts 2 release you can expect that comments in JSON are on by default. You can disable them once this bug is resolved, but it is not recommended.

Even when you use my Struts 2 Json plugin, you’ll find this option activated. Of course you might disable it with something like that:

<result-types>
    <result-type
        name="json"
        class="de.grobmeier.json.plugins.struts2.JsonResult">
        <param name="commentOutput">false</param> <!-- NOT RECOMMENDED -->
    </result-type>
</result-types>

But honestly, you don’t want to disable comments that when you see how easy you make jQuery deal with this “extended json format”. If you use my Struts 2 plugin instead of the official one, you will get a custom content type. Instead of “application/json” (default when comments are disabled) you get:

text/ext-json

With two different content types you are able to mix up pure json requests (which are insecure) and ext-json requests, which are commented and secure. You might want to use the plain when you have insensitive data to transport.

Now, how can you use this new content type in jQuery? It is easy. jQuery offers a feature called Converters. You can add them with .ajaxSetup:

$.ajaxSetup({
  converters: {
    "text ext-json": function( textValue ) {
       var temp = textValue.substring(2);
       temp = temp.substring(0, temp.length - 2);
       return JSON.parse(temp);
    }
  }
});

Do this at a global level, while your app inits. “text ext-json” is no typo by the way - you need it like that. When ever you get ext-json as content type this function will be called. textValue is the incoming JSON String, with comments of course. I use that string and cut off the first two sign and the last two signs which is the comment signs (Note: if you plan to use the official plugin, please see the actual position of the comment signs, they might differ). After you got rid of the comment signs, you’ll probably want to parse the JSON String and return a JSON object.

Now you need to use that content type:

$.ajax({
  url: "yourdata.action",
  dataType: "ext-json",
  success: function(data){
   ... do your stuff - data is now a JSON object  

If you need to use ext-json all over the time, because there is no public data in your app, you can even use .ajaxSetup again to make it default. A complete setup for the .ajaxSetup would look like this:

$.ajaxSetup({
  converters: {
    "text ext-json": function( textValue ) {
       var temp = textValue.substring(2);
       temp = temp.substring(0, temp.length - 2);
       return JSON.parse(temp);
    }
  },
  dataType: "ext-json",
});

With this setup all ajax requests are expecting ext-json by default.

On a side note: the official Struts 2 implementation will happen the next days or has already happened. To my knowledge the plugin does already return comments to the time of this writing (Struts 2.2.3). But it does not send a different response header. I have suggested that, but it is not sure if it will happen. In case they send a “application/json” header instead of a custom one you will need to catch that in your converter. In addition, please check how the comment signs actually look like in the finished application. If in doubt, ask on the friendly Struts mailinglist.

Tags: #Apache Struts #JJSon #jQuery

Newsletter

ABMELDEN