I have seen various headlines about Javascript security issues but never paid any close attention (my bad). But today I was talking to a friend about keeping javascript based widgets small by using a two stage process of loading a small script first, which would then pull down the rest of the script and any associated data.
I assumed that this could simply be done as follows. A site located at say “acme.com” would add the following to their page
Where loader.js then does a
xmlhttp=new XMLHttpRequest();
…
xmlhttp.open(“GET”, “http://widget.com/morestuff”);
…
But no such luck. The XMLHttpRequest is restricted by browsers to only go to “http://acme.com” – the domain from which the original page was served. Good security and strict enforcement of the Same Origin Policy, or so it would appear.
But wait, what if loader.js used the DOM to add a new
var head = document.getElementsByTagName(“head”)[0];
var script = document.createElement(‘script’);
script.id = 'widget’;
script.type = 'text/javascript’;
script.src = “http://widget.com/morestuff.js”;
head.appendChild(script);
Voila, most browsers promptly comply by fetching and executing the javascript from this new source. Even more shockingly, this works just as well for script.src = “http://evilsite.com/somethingbad.js”, i.e. is there is no enforcement of any domain restriction and to top it off you can add parameters to the request.
I am obviously not the first to have discovered this. Quite the opposite, once I started to look around a lot has been written about it. So the points of this post are simply (a) to express my complete disbelief at just how broken this is and (b) to ask whether there is any hope of getting to a better security model.