Thursday, 25 June 2009

ecommerce security

I have just soft-launched my website about ecommerce and web application security: Ecommerce security. I am going to start a separate blogging account for this website containing security tips and advice how to keep ecommerce secure. Hope you might find it useful.

Sunday, 17 May 2009

Math.random notes

There is a very commonly repeated pattern to get a random digit in JavaScript, which looks more or less like this


//get random number between 0 and 3
//BAD EXAMPLE
Math.round(Math.random()*3);


The problem with this line is it returns floating point numbers between 0 and 1, which are multiplied and rounded. But if you run this code in your head a couple of time you will notice that 0 and 3 get half the chances, because the interval which can result in generating them is 50% smaller.:

0.0000 to 0.4999 will yield 0
0.5000 to 1.4999 will yield 1
1.5000 to 2.4999 will yield 2
2.5000 to 3.4999 will yield 3
3.5000 to 4.0000 will yield 4

to test this I run this code in the browser:



//count occurences of needle in hstack
function count(hstck,needle) {
var r = 0;
for (var i=0;i if (hstck[i] === needle) {
r++;
}
}
return r;
}

//run randomness tests
function test_randomness(max,tests) {
var r = [];
var round = Math.round;
var random = Math.random;
for (var i=0;i<=tests;i++) {
r.push(round(random()*max))
}
return r;
}

var big_test_result = test_randomness(4,10000);

console.log(
count(big_test_result,0),
count(big_test_result,1),
count(big_test_result,2),
count(big_test_result,3),
count(big_test_result,4))


the result was:
>>> 1202 2531 2534 2448 1286

We can see that as expected, the extreme resuls are more rare, which makes this random number generator far from perfect. Better approach would be to write a function which removes extremes.


function get_random(max) {
//extend the range
//to cut off extremes
extended_max = max+=2;
var r = Math.round(Math.random()*max);
if (r===0 || r===extended_max) {
r = get_random(max);
}
return r-1;
}


Let's run the test again:


function test_randomness(max,tests) {
var r = [];
for (var i=0;i<=tests;i++) {
r.push(get_random(max))
}
return r;
}

var big_test_result = test_randomness(4,10000);

console.log(
count(big_test_result,0),
count(big_test_result,1),
count(big_test_result,2),
count(big_test_result,3),
count(big_test_result,4))



>>> 1907 1886 1907 1866 1868

This proves that this time results are distributed evenly.

Friday, 21 November 2008

Talking to the bad guys directly

Just examined a feed coming from ebay, that used a rather curious token prepended to the JSON data (leveraging JSONP concept):


throw 1; < don't be evil' >


Security breaches are caused by people's actions. They sometimes might have a moral code, or at least that is what ebay engineers believe in.

Friday, 4 April 2008

Simple pattern for sandboxing JSON

One of the most common threats when getting JSON data from 3rd party websites is evaluating malicious script in the context of your website. If you look at the typical attack patterns it's immediately visible attackers want to access global objects like [window.]document.cookie. Ideally, these objects are not accessible to the parseJSON function, which can be accomplished, with a little help of JavaScript private variables:

var Sandbox = new function() {

//hide all crucial window elements with local variables
//this list needs to be extended

var top={document:{cookie:'access denied'}};
var window=top;
var self=top;
var document=top.document;

//parseJSON will be evaluated in Sandbox's scope

this.parseJSON=function (JSONString) {
return eval( '(' + JSONString + ')' )

}

}

//try get access to the cookie

var stealCookie='alert(document.cookie)'

//evaluate

Sandbox.parseJSON(stealCookie)


This technique, however, cannot be considered the most secure because of how JS handles variables defined without var. What it does is it simply puts it in the global scope. Consider following example:

(function () {
//define in the global scope
//through the lack of var
hack=function(){
eval('alert(this.document.cookie)');
};
hack()
})()


Also see other approach to sandbox JavaScript:
http://dean.edwards.name/weblog/2006/11/sandbox/
and parseJSON implementation:
http://www.json.org/js.html