Re-Securing JSON

Back in March/April of this year there was a lot of hub-bub concerning the discovery of a JSON data leak, or sorts. What it boils down to is “JavaScript is incredibly flexible, even to the degree of letting you redefine basic objects, like Array or Object itself.”

For example, here’s an exploit that works in Firefox 2, Opera 9, and Safari 3. It goes about redefining the global Array object then making it such that whenever a property value is set (even when the array is constructed!) the value is alerted out. In theory, a malicious script could use this technique to swipe data transmitted in JSON (via JSONP or even via an XHR+eval) and send it back to another server.

// From Joe Walker
function Array() {
  var obj = this;
  var ind = 0;
  var getNext = function(x) {
    obj[ind++] setter = getNext;
    if (x) alert("Data stolen from array: " + x.toString());
  };
  this[ind++] setter = getNext;
}
var a = ["private stuff"];
// alert("Data stolen from array: private stuff");

Around the time of that commotion, a bug was filed in the Mozilla bug tracker that begin to explore ways of fixing this issue. It was eventually decided that this was a specification issue and that global objects should not be able to be redefined, due to the inherent problems that they can cause. You can read more about this change, which will be a part of ECMAScript 4/JavaScript 2 in Section 1.4 of the ECMAScript 4 Incompatibilities paper [PDF].

To set about testing this new change, and bringing it into practice sooner rather than later, the Mozilla team implemented and committed a fix to be a part of Firefox 3 (and thusly, JavaScript 1.8). Well, that change landed last week and after a couple minor fires were put out, it made it into the final release of Firefox 3, Beta 2.

If you want to see the change in action, go and download a Firefox nightly and put something like this in the console:

function Array(){
  alert("hello, I found something of yours!");
}
// ERROR: redeclaration of const Array

You’ll note that you now get the above error. This will also be the same for the following global objects:

Thus, if you attempt to redeclare any of those global objects (like I did above) you’ll get the same error. Note that extending properties or prototypes of those objects have remained unchanged (they still work just fine) and this is a change that really shouldn’t effect anyone (save for the malicious types!).

As always, should you spot something tricky, please feel free to file a follow-up bug to the original one (or if you need help localizing it and reproducing it, let me know).

Posted: December 10th, 2007


Subscribe for email updates

19 Comments (Show Comments)



Comments are closed.
Comments are automatically turned off two weeks after the original post. If you have a question concerning the content of this post, please feel free to contact me.


Secrets of the JavaScript Ninja

Secrets of the JS Ninja

Secret techniques of top JavaScript programmers. Published by Manning.

John Resig Twitter Updates

@jeresig / Mastodon

Infrequent, short, updates and links.