Tricks with eval()

Great Resig post regarding JavaScript’s eval() statement:

Last week it came out that, in Firefox (and other Gecko-based browsers) you could dip into the private scope of a function using eval, like so:

// Getting "private" variables
var obj = (function() {
  var a = 21;
  return {
    // public function must reference 'a'
    fn: function() {a;}

var foo;
eval('foo=a', obj.fn);
console.log(foo)// 21

I think the common response to seeing the above was something like: WUH!?!?

I’ll admit I had no idea that the eval() let you essentially peek into any arbitrary scope that you wanted to. What should otherwise be private members of a class or object are suddenly as public as any other. This means there are zero guarantees that your private data and code actually remain private in the JavaScript world.

Moral of the story? Don’t trust data in the browser! We’ve always known to validate any data that comes in to the server – form validation just isn’t enough – but now we know that we can’t necessarily trust our own private variables. If any 3rd party script runs on the same page as your scripts, you’re open to an “attack” of them reading and writing your private variables or functions! No private data or code is safe!

But what if – what if – you control 100% of the JavaScript that runs on a web page – what then? Can you still trust the that your private variables and private functions haven’t been tampered with? Nope. Firefox plugins like GreaseMonkey let users run any bit of JavaScript on any page they want – including your “100% controlled” page.

Don’t get me wrong – if you control 100% of the JavaScript on your page, then it’s certainly not likely that you’re code will be tampered with, but it is possible, and IMO that’s equally scary.

There’s no such thing as secure data or code in JavaScript.

The good news? It’s been fixed. So future versions of future browsers will one day not have this problem. In Firefox. Other browsers? No idea.

1 thought on “Tricks with eval()

Leave a Reply

Your email address will not be published. Required fields are marked *