Hacker News new | ask | show | jobs
by markdown 4528 days ago
Sucks for the people affected by this, but if the result is that more people use google for this, I'd be a happy bunny.

Why would anyone use code.jquery.com, really? They obviously don't mind a third party hosting their js, so why not use the most popular service (google) to increase the chances that users arrive at their website with jquery already cached?

3 comments

> Why would anyone use code.jquery.com, really?

Because webmasters would rather compromise the security and integrity of their site, and the privacy of their users, than pay for the initial burst of bandwidth and latency for first time visitors. jQuery 2.1.0 production, minified and gzipped is still over 30KiB, compared to this thinkbroadband page which is only 6 KiB (and yes this page uses about half a dozen external js resources, including jQuery)

Perhaps it's about time we had a way to specify the hash of <script> source inline so browsers can serve files from cache even if they are from different origins

> Perhaps it's about time we had a way to specify the hash of <script> source inline so browsers can serve files from cache even if they are from different origins

A spec for just that was recently proposed[0], it even has support for a "canonical" script to be used in the event of that the hash check fails.

The good news is a polyfill for this can probably be created today. If CDNs serve their JS with the proper CORS headers, you can request the JS with cross-domain XHR and check it against a hash before eval()ing the script.

The bad news is that the polyfill would require you to allow `unsafe-eval` if you use Content-Security-Policy headers. Depending on your security model, it'd probably be best to host all your resources yourself. Not to mention that using a hash function written in javascript might negate any performance gains.

[0]: http://w3c.github.io/webappsec/specs/subresourceintegrity/

I see no reason to implement any of that in Javascript
The polyfill would need to be in javascript, this is just a candidate spec and isn't actually implemented anywhere yet. Obviously it wouldn't be needed if it was implemented natively. I'm just not sure if it makes any sense to, performance-wise.
This strikes me as something that, without a lot of thought, will expose a user's browsing history (similar to the old "check the visited link color" attacks). Insert script links with a hash, check to see if the browser makes a request.
That was my thought too, the candidate spec for this[0] seems to have taken that into consideration by requiring the scripts to be served with an `Access-Control-Allow-Origin: <origin>` header.

Since the server needs to grant you full cross-origin read permissions to even start the hash check, it's not likely that an attacker could use this to infer more about cross-origin resources than they already can.

[0]: http://w3c.github.io/webappsec/specs/subresourceintegrity/

I think with JSONP you can already make a cross-site request, time the response, and determine whether it was cached or had to be fetched.
Sure, that sounds brilliant: allow anybody who can compute a hash collision to poison other sites' JS libraries. facepalm
That's not hash collision, that's hash preimage attack.

If you can perform hash preimage attack, then faking a JS library is aiming really low.

• You could forge any SSL certificate.

• You could forge any PGP/GPG message (public key crypto is not applied to whole messages, only hashes of them, same with certs).

• You could maliciously modify Git repositories, even those with GPG signed releases like the Linux kernel.

• You could inject malware into any package repository, MITM software updates for all OSes, etc.

Basically security of the entire Internet and all secure software distribution depends on the fact that preimage attack against crypto hashes is impossible (i.e. time and/or energy required to perform a brute-force attack is literally astronomical).

A slightly more sensible approach may be to allow script tags (or any external linking mechanism) to list multiple (trusted) sources, and fallback appropriately.

That certainly feels more inline with how the internet in general was designed.

    <script src="googleapi/jquery,code.jquery.com/jquery,/my/own/version/jquery">
The point they were making is that googleapi and code.jquery.com don't count as trusted (at least not until you verify the hash)
The domains are obviously trusted to a degree. The objective of the hash is just to allow a content addressed[0] clientside web cache, and avoid talking to them most of the time. Good for privacy, security and load times.

[0] http://en.wikipedia.org/wiki/Content-addressable_storage

If you can create arbitrary collisions with something cryptographically secure like SHA-256, malicious jquery is probably the least of our worries.
Having the hash would also be very valuable in case the CDN gets compromised so you don't inadvertently serve js malware to your users.
I want to know what privacy concerns you have regarding static CDNs that you don't implicitly give up by accessing the Internet.
Tracking via 3rd party cookies and E-Tags, plus HTTP Referers as codeonfire said. There's also just the obvious risk of compromise, resulting in millions of sites running malicious code.
Not sending Referer headers to Google.

(Yes, it becomes a problem when you use private browsing, since the cache is cleared when you end the session.)

This is what it's all about. These cdn sites exist not out of good will, but because they give tracking information.
You have to do that at the end-user level if your goal is truly shielding yourself from Google. Wagging your finger at a few of the devs on a news website isn't going to change the millions of websites using client AND server-side Google Analytics, not to mention ads.
I do. Your comment,

> I want to know what privacy concerns you have regarding static CDNs that you don't implicitly give up by accessing the Internet.

implies that the privacy concerns for 3rd party JS library CDNs are null. They are only null if you don't already block or misdirect their other tracking methods.

What makes you think that Google wouldn't be blocked by the same mechanism?
Well let's assume that each URL or domain that is blocked is reviewed by a human who's paid to look at content, not necessarily to have technical knowledge.

They'd be much more likely to know that blocking anything from Google is probably a bad idea/false positive but they've probably never heard of jQuery and when they look at the jquery*.js files all they see is The Matrix.

So if you allow the above assumption, it's less likely that using Google's CDN would present this problem.

So they've never heard of jQuery, but they won't think that googleapis.com looks like a dodgy site as it's trying to pretend to be google.com?
Now that the secret's out, that google won't be blocked, expect the next wave of malware to be served from drive.google.com public links.

There might, just possibly, be a meta lesson here that whack-a-mole blocking doesn't work and is basically a lost cause / waste of time. Try solving the problem another way.

On the other hand, its excellent security theater operating perfectly. Sometimes security is inconvenient, therefore anything inconvenient must be secure, therefore this is great PR.

I believe that countries that block Google block all their domains, including their CDN. This was actually an issue once when one of my "projects" was used by co-workers in China.

Regardless of which CDN you use, having a fallback is a must (see rmrfrmrf's post). Also, if you are making a website (as opposed to a web app), it really shouldn't "break" without JavaScript/jQuery.

Well let's assume that each URL or domain that is blocked is reviewed by a human who's paid to look at content, not necessarily to have technical knowledge.

That's unlikely. Some parental control filters from ISPs were blocking big name childrens charities like Childline. If they blocked that, then that shows they are very incompetent

Better yet, host it locally. More privacy for the user.