We build sites that have a public (non-secured) area and secured (delivered over HTTPS) area and we use jQuery library.
Recently I suggested we use Google CDN for jQuery delivery. Some of my colleagues expressed concerns in regards to security aspect of this way of delivering JavaScript libraries.
For example, they mention the scenario where someone might hijack DNS server and then inject maliciously modified library, opening the door for different security attacks.
Now, if hacker can inject malicious code through Google CDN, then he can probably do the same if jQuery is served from the site itself, right?
It seems that google CDN supports serving libraries over SSL.
Is serving jQuery from CDN really less secure then serving it from the server itself? How serious is this threat?
One way to mitigate the risk is to run a checksum against the file obtained from Google, and compare that to a known-good checksum already in your possession.
In response to a question about whether Google alters these files in any way, Google employee Ben Lisbakken suggested comparing MD5 checksums of a file provided by Google to the canonical version of that same file as obtained from its maintainers' home site. Read comment eight on the linked site for context.
If you're concerned about DNS hijacking, then of course the same concerns would apply to the file as obtained from the "original" site. You also probably don't want to incur the speed penalty of running a checksum against the jQuery file on every request -- unless you're incredibly paranoid. And of course, doing so would remove all advantages of using a CDN.
But assuming you're only somewhat paranoid, you could try something like this:
Make sure you're referencing a unique and specific version of the jQuery file from Google. For example, do this:
http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js
and not this:
http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js
The latter version may return 1.4.2 now, but 1.4.3 tomorrow. If you have a combination of http and https needs, you can use protocol-relative URLs, like this:
//ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js
Initially generate and store your own checksum for this file.
- Periodically repeat the process, and make sure the new checksum matches the old one. If it doesn't, sound the klaxons.
You can do this programmatically, of course. You decide what interval makes sense. Every minute? Every five? You now have the makings of an automatic kill-switch whose sensitivity you can adjust to your preference. The "monitor" routine certainly doesn't have to run synchronously within the application you're looking to secure; perhaps you run a small utility application on the same server just for this purpose.
It's easy enough to test: just alter the stored hash. Since you're referencing a specific file version, the panic button won't be pressed with every minor version update. When you do want to move to a new version of jQuery, change the AJAX API URL on your site and store the new hash.
Is serving jQuery from CDN really less secure then serving it from the server itself?
Yes. If it's an external resource it's always less secure. How could you possibly be sure you know what your customers are really getting if you don't own the source code? And if you're not familiar with CloudBleed, you may want to read up before you continue.
If you do need to load jQuery from an external CDN for performance reasons, please ensure you're using Subsesource Integrity. More information on SRI can be located on MDN.
Lastly, if loading jQuery securely via CDN is a concern due to website performance and the creation of a Single-Point of Failure (and it should be a concern if you're at all familiar with the work of Steve Souders), you're almost certainly better off from a security and performance perspective moving all of your scripts in-house and loading them asynchronously in parallel using Fetch Injection. Just be sure, if you do, you're aggressively browser caching. And if you serve a global audience, make sure you're edge caching those assets.
As your colleagues point out, hijacking a DNS server would be an issue here. It wouldn't be if you served the library from the same host as your site. However, if one uses HTTPS, it is unlikely that the attacker would have a valid certificate on the spoofed site. I do not know how browsers would react to this, but I suspect they would flag the site as unsafe (since some part of it can't be trusted) and act accordingly.
So in short; if the CDN is also accessed using HTTPS, there shouldn't be any large risks.
Edit: Also consider the privacy issue mentioned by Gert G.
If trust exists online then Google is the most trustworthy...
There is no doubt that Google CDN is secure, but problems always always come from user's/server's Internet connection quality.
By the way, if you include the jQuery library with Google API loader script, Google adds some small stat tracking code to it's CDN available JavaScript libraries (about +4kb, see in Firebug) that makes 20kb minified and compressed jQuery library a bit heavy, plus foresee SSL speed.
Anyway minifying/compressing/caching jQuery isn't a problem these days, I suggest make your own...