Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Hack me!
(function(){
// prevent exceptions from escaping outside function (backtrace could be revealing)
try {
// this is ASCII 'Secret!' represented as integers
var secret = [1399153522,1702109440];
var secretlength = 7;
// function that contains secret must finish executing before anything untrusted is called,
// otherwise source of arguments.callee.caller would reveal the secret
return function(){
try {
// this is just minified off-the-shelf implementation of sha1 that takes array of integers (encoded 4 chars per element)
function sha1bin(x,L){var i,j=0,w=[],a=1732584193,b=-271733879,c=-1732584194,d=271733878,e=-1009589776,f=0xFFFF,H='0123456789abcdef';function S(x,y,l){l=(x&f)+(y&f);return(x>>16)+(y>>16)+(l>>16)<<16|l&f}function R(n,c){return n<<c|n>>>32-c}x[L>>5]|=128<<24-L%32;x[(L+64>>9<<4)+15]=L;for(;j<x.length;j+=16){var A=a,B=b,C=c,D=d,E=e;for(i=0;i<80;i++){t=S(S(R(a,5),i<20?b&c|~b&d:i<40?b^c^d:i<60?b&c|b&d|c&d:b^c^d),S(S(e,w[i]=i<16?x[j+i]:R(w[i-3]^w[i-8]^w[i-14]^w[i-16],1)),i<20?1518500249:i<40?1859775393:i<60?-1894007588:-899497514));e=d;d=c;c=R(b,30);b=a;a=t}a=S(a,A);b=S(b,B);c=S(c,C);d=S(d,D);e=S(e,E)}x=[a,b,c,d,e];j='';for(i=0;i<20;i++){j+=H[(x[i>>2]>>(3-i%4)*8+4)&15]+H[(x[i>>2]>>(3-i%4)*8)&15]}return j}
// I'm assuming it's not possible to swap or attach getter to any part of window.location.href
var href = window.location.href;
var href_verification = '', href_escaped = '';
var char_code;
// Those are URL-safe characters. Since I can't trust charCodeAt() to return real values, I'll rebuild the string using this map and compare to the original.
var char_code_to_char = {33:"!", 35:"#", 36:"$", 37:"%", 38:"&", 39:"'", 40:"(", 41:")", 42:"*", 43:"+", 44:",", 45:"-", 46:".", 47:"/", 48:"0", 49:"1", 50:"2", 51:"3", 52:"4", 53:"5", 54:"6", 55:"7", 56:"8", 57:"9", 58:":", 59:";", 61:"=", 63:"?", 64:"@", 65:"A", 66:"B", 67:"C", 68:"D", 69:"E", 70:"F", 71:"G", 72:"H", 73:"I", 74:"J", 75:"K", 76:"L", 77:"M", 78:"N", 79:"O", 80:"P", 81:"Q", 82:"R", 83:"S", 84:"T", 85:"U", 86:"V", 87:"W", 88:"X", 89:"Y", 90:"Z", 91:"[", 93:"]", 94:"^", 95:"_", 97:"a", 98:"b", 99:"c", 100:"d", 101:"e", 102:"f", 103:"g", 104:"h", 105:"i", 106:"j", 107:"k", 108:"l", 109:"m", 110:"n", 111:"o", 112:"p", 113:"q", 114:"r", 115:"s", 116:"t", 117:"u", 118:"v", 119:"w", 120:"x", 121:"y", 122:"z", 123:"{", 124:"|", 125:"}"};
// calling escape() is not an option, so here's custom solution.
var char_code_to_escaped_char = {37:"%25", 38:"%26", 39:"%27", 43:"%2B", 47:"%2F", 59:"%3B", 61:"%3D", 63:"%3F", 94:"%5E", 124:"%7C"};
for(var i=0; i < href.length; i++) {
// cast in case charCodeAt returned object with evil valueOf
char_code = 0+href.charCodeAt(i);
if (!(char_code in char_code_to_char)) return;
href_verification += char_code_to_char[char_code];
href_escaped += char_code_to_escaped_char[char_code] || char_code_to_char[char_code];
// simply appends to secret array. It's bit-twiddling equivalent of "secret" + href
secret[(i+secretlength) >> 2] |= char_code << 24 - (i+secretlength)*8 % 32;
}
// if charCodeAt lied, then char_code_to_char was mapped to different letter, and won't equal href.
if (href_verification != href) return;
// hashed secret+url and url is sent to server, allowing server to verify authenticity of the URL.
// (although hashing method should use HMAC to prevent extension attacks)
alert('window.location.href = http://example.com?sha1=' + sha1bin(secret,8*(secretlength+href.length)) + '&url=' + href_escaped);
} catch(e) {}
}
} catch(e) {}
// arguments could be another way to store the secret - the upside is that source of the function wouldn't contain the secret.
})()();
@kornelski

This comment has been minimized.

Copy link
Owner Author

commented Jan 3, 2011

This is code of a bookmarklet that is supposed to read URL of page it's executed in a way that cannot be spoofed with CSRF.

Description on JSMentors list

Deletion of String.prototype.charCodeAt reverting to built-in function is actually a WebKit bug, so I've removed that bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.