Mitigating CVE-2019-11358 in old versions of jQuery
A few months ago, a new vulnerability was found in jQuery, affecting all existing versions of jQuery. It was fixed only in the new version 3.4.0.
The SNYK website has a lot of detailed information about this ‘Prototype Pollution’ vulnerability, so I won’t go into that here. For those interested, follow this link :
https://snyk.io/vuln/SNYK-JS-JQUERY-174006
What I find interesting is the fact that no patch has been made available for older versions – the argument of that being that they already contain other vulnerabilities, so it has no sense patching them. While that is true for most of them, there are a few versions which were still free of vulnerabilities – most notably version 1.12.2. The difference between 1.x and 3.x is quite big, so upgrading means breaking existing code (in most cases). This has serious consequences for complex/older applications. Up until now 1.12.2 was still the safe version for those depending on the 1.x code-base, but now that safety net is gone.
Patching this vulnerability is ridiculously easy though! All it takes is changing one line of code. _One_ line of code! And this one-liner doesn’t even break anything. Given the popularity of the framework and its widespread usage, it would’ve been really nice if a patch had been released for other versions too. But since it hasn’t been, we will provide you with the fix! That means you will not necessarily need to upgrade your jQuery version to mitigate the vulnerability. While this might prove valuable for situations where upgrading is not a possibility (on a short term), I do want to point out that keeping your libraries up to date is important! This patch should be used as a temporal fix; these older versions of jQuery are end-of-life and should therefore be upgraded to the latest stable version as soon as that is possible.
Fixing it yourself, manually
If you don’t trust me, just trust the people from jQuery. This is the official commit that fixes the issue:
https://github.com/jquery/jquery/commit/753d591aea698e57d6db58c9f722cd0808619b1b
This means that all you need to do is:
- Make sure that jquery is running locally, or create a local copy. By local, I mean that you’re not including it from a CDN (such as http://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js), but that you’re putting it in the webroot of your own domain.
- Look up the line that says:
if ( target === copy ) {
and replace it withif ( name === "__proto__" || target === copy ) {
just like they’ve done in the commit (see link mentioned earlier)
That’s it!
Like I said: ridiculously easy.
(The other lines that show up green in the commit are from a unit test that checks the fix. You don’t need to include that in your code)
Downloading the fix from us
For those who feel uncomfortable making manual changes, we’ve made a patched version of jquery-1.12.2 available. The reason we choose this version:
- Upgrading from 1.x to 3.x has the most backward compatibility problems
- You’re more likely to find this version in software that is not actively maintained anymore
- 1.12.2 is the most recent 1.x version that has no other vulnerabilities besides this one.
The patched version can be found in our github account (mostly for availability reasons):
https://github.com/bitnesswise/jquery-prototype-pollution-fix
Testing your website
To know if your application is vulnerable and/or if you have applied the fix correctly, you can execute the following code in the developer console of your browser:
var maliciousJson = '{ "myProperty" : "a", "__proto__" : { "isVulnerable" : true } }'; var testObject = jQuery.extend(true, {}, JSON.parse(maliciousJson )); if (typeof {}.isVulnerable !== 'undefined' && {}.isVulnerable === true) { alert("Bad news :(\nYou're (still) vulnerable to Prototype Pollution") } else { alert("All Good! :)\nYou're NOT vulnerable (anymore) to Prototype Pollution") }
Simply copy-paste it and hit enter: an alert will pop up telling you whether or not you’re (still) vulnerable. This is a screenshot of what it will look like:
WordPress
Nice detail: WordPress (which is used by this blog) has backported a similar fix into their own version of jquery too. If you open the developer toolbar and look at the sources of this blog you’ll see jquery 1.12.4 is loaded (jquery.js?ver=1.12.4-wp
). That looks like a vulnerable version at first sight, but by executing the code snippet above in the console you’ll see that they have fixed it in the version wordpress includes. Nice job!