Some Thoughts Regarding Caja
Yesterday, Yahoo! made some announcements regarding The Future™ of many of their high profile properties. Specifically, they’re (slowly) opening up, enabling third-party developers to build applications that can be seen on and interact with your My Yahoo! page, or your mailbox. I think this is a great step, and one I wish they’d made before they laid me off.
If you’ve paid attention to any of Doug Crockford’s presentations, you’ll know that the browser security model is simply broken-as-designed. The internet, therefore, is a place where one can barely trust first-party code, much less code written by your neighbor. You have to keep a constant eye out for new cross-site scripting vectors, and be very careful about how you filter third-party input before making it available as “user generated content.”
There are two broad paths to take to this end:
Code sanitization, which reads unknown code, processes it, and outputs a sandboxed version (if possible). Caja is the best known example of this tact.
Static analysis, which reads unknown code, parses it, and gives a thumbs-up if it only does known-safe things. AdSafe is a work-in-progress along these lines.
Yahoo!’s running with the former, so let’s dive in.
window objects. This means that it must not gain direct access to any DOM node, as every DOM node enables you to crawl back up to
event objects are right out as well, as they contain dangerous references as well. Really, when you get right down to it, you have to throw out practically everything of practical use.
Caja is a capability-based system, meaning in practice that it begins by defining an extremely restrictive sandbox in which code must run, and enabling well thought-out bits of functionality by selectively injecting access as needed.
Think of it this way: when you hand your car to a valet, you would be better off if you gave them the valet key, which only enables them to drive the car. You shouldn’t give them your key, which would also let them rummage through your glove box, etc. In the same way, you shouldn’t give a program access to everything in the DOM if it’s only supposed to change a background colour in a particular location. You’d be better off if you could restrict it’s scope of access. Caja attempts to do this.
As a quick demo, let’s look at the following code:
<script src="searchbox.js"></script> <link rel=stylesheet href="searchbox.css" /> <form> <input type="text" size="60" name="q"> <input type="button" value="Search" onclick="doSearch(this)"> </form>
After “cajoling”, it will look something more like:
... IMPORTS___.htmlEmitter___.p('form') .a('onsubmit', 'return false') .ih(' <input type="text" size="60" name="q">\n' + ' <input type="button" value="Search"' + ' onclick="return plugin_dispatchEvent___(…)">\n') .e('form'); ...
I’d much prefer more thought to be put into AdSafe, which sets up the same sort of wrapped-object sandbox, as well as a series of rules which third-party developers must follow. The system them simply verifies that they have done so, rather than rewriting their code to ensure that they have. If the rules are solid, the effect will be the same as can be achieved with Caja, but much more elegant, and with more respect for the fundamentals of the web.
Crockford has (finally) put up some example code on the AdSafe site. I’d suggest that you go take a look at it. It looks like a very interesting way to program indeed.— Mike West