Showing posts with label Content Security Policy. Show all posts
Showing posts with label Content Security Policy. Show all posts

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.

Sunday, 19 June 2011

XSS (Part 4) - A New Hope

So this is my last post in my series on XSS and I hope to follow up on my previous 3 posts by offering more detail on how you might implement a solution to XSS by progressing through the stages of the XSS Mitigation Maturity Model (MMM).

There isn't much point in offering any advice for the None and Basic levels; there is nothing to do for the None level, and the Basic level is what people currently do if they follow the advice online.

The purpose of the Intermediate level is to automate output encoding.  The reason this is an advantage over the Basic level is it takes the burden off of developers to manually apply (the correct) output encoding everywhere in the application.  Relying on developers to do this perfectly is unreasonably and to be honest not really where you want them focusing their efforts.

If you are fortunate you may be using a web development framework that offers automated contextual output encoding, however I am not familiar with enough different frameworks to know how broadly supported such a capability is; I'm going to assume not very.  Implementing this yourself involves extending your framework that writes data and code to web pages to understand the context of where the data or code is being written.  Typically this will have mixed results, it will work well for simple pages, but not so well for complex pages or pages where a combination of data and code is written simultaneously.  This limitation is acceptable though as we can use it to isolate those areas where we cannot use automated contextual output encoding and make those areas the focus of XSS testing.  For testing purposes your security team should be able to come up with a suitable range of tests or tools that test for basic XSS attack vectors.

Whereas the Intermediate maturity level can be applied to existing code with a manageable amount of effort, the Advanced maturity level implies creating a web page that is designed to be secure against XSS.  It's important to understand that the design of a web page should never just be about mitigating XSS, that wouldn't be very practical, but we can design pages so that speed, size and functionality are not the only considerations; we also consider security.

At the beginning of my first post in this series I talked about FireFox 4 as offering exciting new defenses against XSS, I was referring to it implementing the Content Security Policy (CSP) proposed standard.  The CSP allows a browser to restrict the scripts that run in the page to a white list provided by the server (as an HTTP header).

The CSP does impose constraints though, namely the page is not allowed any in-line script, instead all script must be sourced via HTML script tags.  Whilst this may seem like an unrealistic burden, it is just a design criteria, and in fact it is one that is satisfied by following the design guidelines of Unobtrusive Javascript.  The Unobtrusive Javascript approach offers numerous advantages (including making it easy to optimise for speed and size, and separating functionality from presentation), but does need to be designed into the construction of web pages and be understood by developers who implement it.

While implementing the CSP in your web app will be invaluable in defending against XSS, contextual output encoding still needs to be applied.  However, the constraints of the CSP and Unobtrusive Javascript make the accurate automated output encoding of data and code much easier as the context is trivial to determine; all Javascript will be in Javascript files, all CSS will be in CSS files, and the CSP will stop any Javascript or CSS from being written to HTML files.  To be fair it's Unobtrusive Javascript that helps the most as even without the CSP if you contextually apply output encoding that will eliminate most XSS (except perhaps in HTML attributes and the use of "javascript:" protocol handler).

As with the Intermediate level, any exceptions to designing security into a web page need to rigorously tested.

So there you have it.  It wasn't that painful was it?  Clearly I have only touched upon the topics involved and you would have to do some research yourself in order to flesh out a detailed technical solution at each maturity level.  But hopefully this post has given you some ideas about where to start.