Javascript: window.onerror, origin, and "Script error"

You've always been able to collect the server side error logs for server side code, allowing you to track down those strange corner cases that users always stumble into, but developers and QA never think of. With the increasing complexity of Javascript applications doing the same trick for your client side code is rather important. In theory registering a window.onerror function which reports errors back to your server should do this, but, except in the most simple of cases, this isn't the whole story.

At some point (many years ago), someone noticed that allowing an evil attacker to have a page which registers a window.onerror, and then uses a script tag with a src of something that's not Javascript on another domain can be sorta interesting. Evil attacker's onerror will be given a parse error, and may well be passed some of the content of the document which couldn't be parsed as Javascript.  If I were to, for example, point the src attribute at Facebook, my onerror may well be passed something that contains some of your personal data from Facebook and CSRF tokens (assuming you're logged in there.)

To fix this information leak, some browser vendors (at least Google and Mozilla, I haven't checked anyone else) decided to make onerror check that the origin of the script causing an error matches the origin of the page. If the origins don't match then the error is sanitised to remove any potentially sensitive information: it becomes one the annoying "Script error" in "" on line 0. The origin of the script which registered the onerror is irrelevant, just the page and the script with an error matter.

So, why's this annoying? If all of your Javascript is hosted on the same domain as all of your content, then you're fine. If you have any 3rd party Javascript on your site, you're not going to get useful error reports when it goes wrong. Still, so far, so good. But what if your Javascript is hosted on a different domain(s) to your content? This'll probably be the case if you use a CDN, or if you have multiple sites which share a central collection of Javascript. Now you're going to see a whole load of "Script error"s, and very few actually useful error reports.

This is significantly less than ideal.

Fortunately there's a proposed solution, which is implemented in Firefox and Opera, though doesn't seem to have found it's way into Chrome yet. That solution involves attaching crossorigin attributes to your script tags, and sending an Access-Control-Allow-Origin header with your scripts which will match your page's origin. As soon as you do that, your onerror (again, where that's registered from doesn't matter) will start getting useful information.

This nicely fixes the Javascript on your own CDN problem but, of course, there's still a case where this doesn't work entirely satisfactorily.

If you have sites on multiple domains that use the same, common, Javascript from a different domain, what do you set your Access-Control-Allow-Origin header to? The spec for the header says it's a space separated list, as does the W3C's wiki on the matter, however the processing part of the spec fails to mention this and demands that it's either "*" or a case insensitive match for the Origin header. Mozilla have stuck with this latter interpretation. It looks like the bug's in the spec, though a note on the definition of the header suggest that the W3C have themselves consigned themselves to this interpretation.

So, erm, yeah. What to do? I think you're basically stuck setting it to "*". This seems a tad sad. Any other option will run into problems with caching.

Update: since writing this I've raised the inability to make use of a list of origins as a bug on the W3C bugtracker. I fully expect a public mocking for this.