Monday, 8 August 2011

How We Built the Recx Security Analyzer Chrome Extension

It’s not rocket science
The purpose of this post is to demonstrate that usable security tools don’t need to be rocket science and to hopefully inspire those of you with other ideas to write your own browser extensions. The reason we wrote the Chrome extension in the first place was that we felt that there were a number of low hanging fruit security attributes that should be accessible to development and quality assurance processes in a clear and easily understandable manner. We've also already had some feedback from security professionals that they sometimes forget to look for these issues and simple functions they can access in their browser are a good way to ensure they are consistent.

Why a Chrome extension?
The reasons we chose to write a Chrome extension was really two fold. The first is that development and QA already use a browser so why not just make it accessible via a tool users are already familiar with? The second was the thinking that Google’s Chromium team have done all of the heavy lifting, implementing HTTP, SSL/TLS, the DOM, JavaScript engine, Cookies etc. and provided programmatic access to the browser. So why would we want to re-implement the wheel in no doubt a lacklustre fashion over many months (if not years) and be plagued with corner cases and related dramas? The ideas we discounted included:
  • Writing a web security proxy or plug-in for an existing one. Discounted as we thought it would not be as intuitive or quick to install, set-up and use on a daily basis by non dedicated staff.
  • Writing it in C, Java, C#, or Python. Discounted as we thought parsing everything and building a UI would be a lot of work for no benefit. We did look at some Java / C# web browser libraries and felt they would be filled with the corner cases we mentioned due to their inability to keep up with the development speed of modern browsers. Or in the case of the Internet Explorer COM object a pig to work with that doesn't always expose easily everything we wanted (that prototype is in the hours wasted bin).
The extension’s components
So, the extension is made up of three components, the background element, the content element and the main popup element. All three of these components perform distinct functions which are described in detail below.

The background element
The background element is used to register the right-click context menus and the call-back to handle any processing of these events. When the user clicks on the right-click context menu the call-back is executed, the type being requested is understood, the URL obtained. Then a new tab is created with an instance of the popup element. At which point all control is handed to the popup for further processing. We encode the Chrome tab ID and the URL of page, frame or link being analysed by the user into the request parameters to the popup to perform a method of IPC.

The page content element
The page content element is used to parse the DOM of the requested page (as seen by the user). This is broken out into to two main functions. The first enumerates all the of page’s meta headers looking for security related attributes. The second parses the page looking for forms and form elements. These two functions build an object that contains the results ready to pass to the popup element. In order to reduce non-essential page load overhead we don’t execute this on every page load. Instead we only inject and execute this extra code on a case by case basis when the user requests us to. We found this had a profound impact on general Chrome performance and seemed to make us good browser citizens. Finally we register an IPC event listener looking for requests for the popup element to return the newly built results object. When a request comes in from the popup element we then return the results object as instructed.

The popup element
The popup is the main component and holds a majority of the logic and all of the user interface. This is behind the icon when the user clicks on the Recx icon or appears in the tab when the user clicks on the right-click context menu. The popup then does the following things:
  • The popup works out how it was called (browser icon versus right-click context menu) and the URL being analysed and the tab ID.
  • Performs an XMLHttpRequest to the URL requested, so inheriting any session cookies in order to obtain the HTTP headers from the server. Analyses any security related HTTP headers and builds the UI with the results. It also then builds the ‘All HTTP headers’ hidden DOM element for advanced users.
  • Enumerates all cookies within Chrome looking for those cookies that relate to the URL requested. Analyses them and builds the UI with the results. It also then builds the ‘All cookies’ hidden DOM element for advanced users.
  • Injects our content element into the Chrome tab for the page requested using the tab ID. Chrome provides a way for us to inject this content element not into the actual page but a container which has full access to the pages DOM. This then performs the operations described previously to analyse the DOM for security issues.
  • Sends a request via Chrome IPC to our content element for a copy of the results object and then receives it via an asynchronous call-back. Analyses the returned object for any security issues and builds the UI with the results.
  • Finally the popup element builds the rest of the UI using a mixture of JavaScript and DHTML and makes it visible to the user.

And ‘ta-da’ the user is then presented with the results. All the strings are actually pulled in from a locale file so if we ever want to dust off our schoolboy German, Spanish or French (or put our faith in Google translate) we can in theory easily support different languages.

Time effort spent
We thought it might be interesting to provide a breakdown of the time we spent developing the extension (but not the upfront research/wasted prototype code). We're going to caveat all of this with that we've never written a browser extension before, not written a tremendous amount of JavaScript recently and we're not intimately familiar with all the properties of every DOM object. The break down below is for all effort to-date across the team. In this time we've had three releases, the initial release, a spelling patch (doh!) and a new feature release.
  • Reading how to use the Chrome extension API: ~ 8 hours
  • Reading up on DOM element properties: ~2 hours
  • Writing code: ~14 hours
  • Testing: ~8 hours (across multiple versions of Chrome / OSs on multiple sites)
  • Bug fixing: ~ 3 hours
  • User interface: ~4 hours
  • Re-factoring because of security issue (see below): ~2 hours
  • Reporting bugs to Google: ~1 hour
  • Packaging, screen-shots and release: ~1 hour
The funny
While we were writing this extension we fell afoul of a security issue (which our SDLC code review caught before release) which is always amusing when you’re in the business of software security consultancy and writing security software. The root cause was that we were using innerHTML when building the results DOM with untrusted data instead of innerText. Net result is we would have been vulnerable to Cross-Site-Scripting had we shipped with it. There was a surprising amount of re-factoring required to move away from the use of innerHTML to innerText as you end up doing a lot of DOM building. But hey, who says security was free (aka don't take short cuts)? Anyway, for those of you considering writing your own extensions we recommend you read both the Chrome extensions documentation in detail (which does warn you in numerous places) and the recent blog post by the Chromium team titled ‘Writing Extensions More Securely’.

The browser as the next web security tool platform
We’re pretty passionate about the fact that we believe the browser will make a solid foundation for development and QA friendly web security vulnerability testing and regression tools. There are already examples of other extensions in the Chrome web store that provide a more penetration tester centric tool-set. This demonstrates to us that others clearly feel the same about the power of the browser. We already have our eye on a number of experimental Chrome extension APIs that once mainlined by Google will allow us to bring other more powerful tool-set to market. In the mean time we expect to further refine, polish and extend the existing extension.

Getting the extension, taking it for a spin and wrap-up
The extension is available free from the Chrome web store (23 users and counting – only several of which we suspect are our parents and siblings), please provide us feedback or feature requests.

If you want to see why we wrote this tool and the somewhat bi-polar nature of web security try running our plugin against (don't check ours out.. as err..):
Finally, we hope you found this post explaining our mindset and how we glued all the bits together informative and inspiring.

No comments:

Post a Comment