This made me sit up and take notice. The libraries these researchers were checking for were 72 of the most popular open-source projects out there — libraries like Angular and jQuery that we all use every day. I’d never really stopped to think whether an outdated version of jQuery could present a serious security threat. And I had (almost) certainly never gone back to update an old version of jQuery on a website I had made. Was this something I should have been doing?
My Career as a L33t H4x0r
So, now I was curious and decided to see if I could use an outdated version of jQuery to hack one of my own pages. I started off searching for “jQuery security vulnerabilities” and pretty soon stumbled across this issue on jQuery’s GitHub repo. People were pointing to this as a potential cross-site scripting vulnerability which meant that an attacker could execute arbitrary code at the request’s origin. That sounded promising …
The issue was easy enough to reproduce — the problem was that jQuery was executing every
$.get() request — but that was as far as my excitement went. As one of the jQuery maintainers pointed out in the thread, this “exploit” was similar to including third party code via
<script> tags. This wasn’t likely to bring my website to its knees and was hardly the stuff hacking movies are made of.
Take 2: A Bit of Session Hijacking
Not wanting to be deterred, I imagined what I would do if the exploit had worked and I could execute arbitrary code on a user’s computer. One thing we are often warned against is session hijacking where a malicious script can manipulate a user’s cookies to gain unauthorized access to information or services they are logged into. So, I thought I’d try my hand at that.
I started off by attempting to print out the cookies of a service I was logged into (a simple Rails app which used the Devise gem for authentication). I opened the browser console and entered
It’s a Jungle out There
Ok, so it turns out I’m not the world’s best hacker, but joking aside, it is actually a jungle out there! Browser security has come on in leaps and bounds in the past years (HTTPOnly cookies being an example in point), but online criminals are always a step or two ahead. The list of possible attacks is seemingly endless and as you build more complicated applications, the libraries you use will (unwittingly) introduce vulnerabilities into your code base. Keeping these libraries patched to the best of your ability, or at least being aware that some are potentially insecure, has to make sense, right?
Our original outdated version of jQuery shouldn’t prove too challenging to update, but what about when an application starts to grow? Luckily there are a few tools and services to help you. For example the npm-check package does what it says on the tin and will check for outdated, incorrect, and unused dependencies. It will also kindly provide a link to a package’s documentation so you can decide if you want the update. There are also services such as Greenkeeper.io and Snyk which automate the process, but these are starting to stray into Node territory.
One for the Road
There’s one more tip that I’d like to share which goes some way to mitigating the danger posed by third party scripts. This is to verify third-party content using subresource integrity (SRI). You might have come across this if you’ve attempted to include jQuery from the jQuery CDN lately. You’ll see something like:
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
What’s new here is the
integrity attribute on the
<script> tag which can be used to specify a base64-encoded cryptographic hash of the resource you’re asking the browser to fetch. This effectively allows the browser to ensure that resources hosted on third-party servers have not been tampered with.
Using SRI is now a recommended best-practice. You can use the SRI Hash Generator to create hashes of your own.