Thursday, 20 February 2014

Unobtrusive JavaScript and JSON Data Islands

I saw a tweet the other day from Jim Manico
That link is to http://www.educatedguesswork.org/2011/08/guest_post_adam_barth_on_three.html.

The advice is basically to have more or less static HTML and JavaScript and all dynamic data should come from a JSON request.  Not bad advice.

Reading the article reminded me of a similar approach that I once proposed, using Unobtrusive JavaScript. Unobtrusive JavaScript is an approach to developing a web application that clearly separates HTML from JavaScript from CSS.  Now if you are a developer then rest assured this is not an approach created by a security guy who prioritises security above all else, this is an approach suggested by people who actually know what they are talking about.  The Wikipedia page has the details, and interestingly is doesn't even mention the word 'security'.

So why is Unobtrusive JavaScript good for security?  Well the best approach to preventing XSS is to use contextual output encoding, however that hard part of that is the 'contextual' bit.   It seems that figuring out on the server side how the data being bound to a template is going to be interpreted by the browser, as either HTMl, JS or CSS, is often quite difficult.  But if all the HTML, JS and CSS reside in different files, then the context couldn't be easier to determine, which makes output encoding a much simpler task.  Additionally, this separation can be enforced by using the Content Security Policy (CSP) so you don't get any naughty developers slipping in JS where they shouldn't.

Of course if you are going to be suggesting Unobtrusive JavaScript then I wouldn't even mention security, there are so many other benefits that make it a good idea that you probably don't want any security related ulterior motives to be an issue ;)

So there are obvious similarities to what Adam Barth suggested, but a difference that I proposed was an alternative to using AJAX requests.  So instead of making a separate network request for the JSON data another option is to put the JSON data inside the the HTML, in a 'JSON data island' (sadly it seems someone else beat me to coining this phrase).  The comes from XML Data Islands, but obviously if the data is going to be used by JS it makes more sense for it to be JSON than XML.

The JSON data island could be implemented as a hidden <div> element or a <script> element with type="application/json".

The basic advantage is that it saves a network request.  Admittedly this makes more sense for HTML pages that wouldn't be cached, so its appropriateness does depend on how the web application is architected (in terms of caching optimisations made).  The data island would also need its own output encoding as the appropriate encoding for the server to do is to JS encode the data going into the JSON and then HTML encode the entire data island contents.

Sadly my proposal represented too much of a change to the web application I suggested it for, so if you like the idea, I hope you have better luck than me.

No comments:

Post a comment