Secondly, my esteemed colleague, Jasvir Nagra, has put together a really nice playground for Caja. Have a go, it’s pretty.
That is all.
Secondly, my esteemed colleague, Jasvir Nagra, has put together a really nice playground for Caja. Have a go, it’s pretty.
That is all.
Caja has long been used by Yahoo!, ironically, to protect users from malicious gadgets on their Application Platform but until recently has been a bit of a poor relative at Google. So, I’m pleased to report that it is now in use to protect Orkut users.
Because Caja is open source, we don’t necessarily find out when people use it: do you know of someone using Caja? Leave a comment!
One of the hardest parts about using Caja (which, by the way, is now far and away the most successful capability project ever) is debugging. Because of the transforms Caja must do to render your code safe, even something simple like
x.a = y.b + z.c();
$v.s($v.ro(‘x’), ‘a’, $v.r($v.ro(‘y’), ‘b’) + $v.cm($v.ro(‘z’), ‘c’, [ ]));
if we ignore all the wrapping code that is generated. Whilst you can certainly get used to reading this and translating it back into your original source in your head, so you can use, say, Firebug to debug, it’s pretty painful at best.
By the way, if you want to play with Caja, it’s now easier than ever, using the new Appspot-based Caja Playground.
Yes, you read correctly, if your code cajoles, it will run in Firefox and IE. This is amazing and its value cannot be overestimated.
Yahoo! yesterday launched their new development platform for My Yahoo! and Yahoo! Mail, which uses Caja to protect users from malicious gadgets. This means Caja suddenly got 275,000,000 users. Wow! I guess this makes Caja the most widely used capability language ever.
But what I’m most excited about is that there’s virtually no mention of Caja at all. Why? Because Caja gives you security without getting in your way – the fact that end users don’t need to know about it all – and even developers hardly have to care – is a great success for Caja.
A few weeks ago, we invited a group of external security experts to come and spend a week trying to break Caja. As we expected, they did. Quite often. In fact, I believe a team member calculated that they filed a new issue every 5 minutes throughout the week.
The good news, though, was that nothing they found was too hard to fix. Also, their criticism has led to some rethinking about some aspects of our approach which we hope will make the next security review easier as well as Caja more robust.
You can read a summary of their findings.
Tim Oren posted about Caja.
End of message.
Its been a while since I wrote about Caja but we’ve been working hard on it and it has come along in leaps and bounds, thanks to my excellent team at Google.
Today I’m very pleased to be able to point you at a test gadget container which supports Cajoling of gadgets. This is based on the open source OpenSocial container, Shindig.
Here’s the announcement, and there’s also some documentation on how to get things working with Caja. We’ve even included a couple of malicious gadgets which are defeated by Caja.
Feedback, as always, welcome.
An obvious place to use Caja is, of course, in OpenSocial. So, a bunch of us at Google have been experimenting with this use case and the first outcome is an update to the container sample which allows you to try running your gadget Caja-ised (gotta think of a better name for that). We even have instructions on how to Caja-ise your gadget.
We haven’t tried many gadgets yet, but the good news is the example gadgets worked with (almost) no change. It seems clear that more complex gadgets are not likely to survive without at least some change but we don’t yet know how hard that’s going to be. Feedback, as always, welcome! And don’t forget to join the mailing list to discuss it.
 Right now, because Caja-ised code gets pushed into its own sandbox, you have to export any functions that need to be visible to the rest of the page (for example functions that get called when you click a button) – right now, you have to explicitly perform that export but we expect to be able to remove that requirement.
From now on, all development will be done out in the open. External developers are welcome to come and play, too. Join the mailing list. Write code! Find bugs! Laugh at my mistakes! Have fun!
Caja will be open source, under the Apache License. We’re still debating whether we will drop our existing code for this as a starting point, or whether we want to take a different approach, but in any case, there’s plenty to be done.
Although the site has been up for a while, I was reluctant to talk about it until there was some way for you to be involved. Now there is – we have a public mailing list. Come along, read the docs (particularly the Halloween version of the spec) and join in the discussions. I’m very excited about this project and the involvement of some world class capability experts, including Mark Miller (of E fame) who is a full-time member of the Caja development team.
Now that we’ve deployed the most successful capability language ever, it’s time to start thinking about the rest of the stack, and one end of that stack is the operating system.
Luckily, thinking in this area has been going on a long time – indeed, capabilities were invented in the context of the OS, though for a long time were thought to be the exclusive domain of specialised hardware. Some of that hardware ended up being extremely widely deployed, too, so don’t think this is the stuff of lab experiments only. Sadly, though, despite the hardware supported capabilities, these were not generally exposed up to the level of the kernel/userland interface; they were thought to be useful only within the kernel (with one notable, but not very well known or widely used, exception),
However, more recently it has been realised that capabilities are not only useful in userland, but also can be implemented on top of commodity hardware, resulting in a crop of new capability operating systems. But these still suffer from the problems that traditional capability languages have suffered from: they need the world to be completely reinvented before you can use them. Because the capability paradigm is fundamentally different from the ambient authority ACL-based world we live in, no existing software can fully enjoy the benefits of capabilities without at least some rewriting.
So, the interesting research question has now become: how can we move toward this world without having to rewrite everything on day one? Some progress has been made with mapping POSIX onto capabilities. Heading in a completely different direction is the idea of running existing OSes as guests on a capability system. Yet another approach is to apply capabilities to more restricted domains: one that I have been involved in is the idea of hosting untrusted software “in the cloud”, in the same vein as Google App Engine. Because this software is all new, changing the way it has to work is not a big deal.
But the thing that interests me most is the work being done on FreeBSD, which allows capability-based code to coexist with (or even be contained within) existing POSIX code. This provides a genuine, believably workable, migration path from existing systems to a brave new capability world. We can move one application (or even one library) at a time, without breaking anything. Which is why I am pleased to be able to say I am involved in this work, too. What’s even better is this work is by no means specific to FreeBSD – the same principles could be applied to any POSIX system (so Linux and Mac OS X would be good targets). Just as we have seen success with Caja it seems to me that this route can deliver success at the OS level, because it allows a gradual, piecemeal migration.
Unusually for me, I have not interrupted my narrative flow by naming or saying too much directly about the various things I link to – however, I appreciate that following links in the middle of reading can get distracting, so here are many of the links again with some explanation…
CAP computer: the project that invented capabilities.
IBM System/38: more capability hardware.
AS/400: derived from the System/38. Although this had capabilities, they were not exposed to userland. Very widely used commercially.
KeyKOS: a commercial capability operating system.
Amoeba: an experimental capability system – like Caja, it tends to advertise its other virtues rather than describing itself as a capability system.
EROS: another experimental capability OS – originally intended to provide robustness, not security. The first to run on a standard PC.
Coyotos: by the original designer of EROS. Now also discontinued (can you spot a trend here?).
Plash: the Principle of Least Authority Shell. This shell runs on Linux, figures out from the command line what any particular invocation of an executable should have access to, creates a sandbox with access to only those things, then maps POSIX calls onto the sandboxed things.
L4: a modern capability-based microkernel.
L4Linux: Linux running on top of L4. Although this is nice for things like driver isolation, it seems like the wrong direction because it does not assist with exposing capabilities to userland.
FreeBSD Capsicum: a capability mode for FreeBSD. Whole executables can opt in to this mode, coexisting with POSIX binaries. Even more interestingly, libraries can spawn off capability-mode subprocesses whilst effectively remaining in POSIX mode themselves. This allows the transparent implementation of privilege separation. This project has also been sponsored by Google.
How did you bring up a compiler so quickly â€“ what environment, what development system is the compiler written in?
Firstly, I’ve had a lot of practice – I’ve been writing (small) compilers for at least 20 years now. I’ve been writing code for over 35 years. That helps. But to talk about the reproducible parts of what I did…
Firstly, I wrote the compiler in Perl. I like Perl for quick hacks, and I also like to write Perl code “properly” – that is, I use modules and object oriented programming, not great monolithic blocks of Perl gibberish.
Secondly, I used a compiler-compiler, in this case, Parse::Yapp. This uses a specification language rather like BNF, and exactly like its predecessors, yacc and bison, so there was zero learning curve for me there.
I do remember finding yacc extremely puzzling when I first started with it, so if you are new to this, I would highly recommend Antlr and Antlrworks. The only reason I did not use Antlr is its Perl support seems to be pretty experimental, and I didn’t want to spend time fighting the tools. Otherwise, Antlr is vastly superior to the whole yacc/bison/yapp thing. Antlrworks lets you interactively explore your parsing, complete with diagrams. It really is quite awesome and I love it.
Thirdly, I avoided using a lexer generator. In my experience, these are fiddly and more trouble than they’re worth, especially if you’re writing in Perl, where you have very nice pattern matching tools that allow you to write a lexer in not many lines of code (about 60 in the current version of Stupid).
Fifthly, I kept the grammar of Stupid simple – I make life harder for the programmer in order to make the parser simpler. This is for two reasons, firstly, I was in a hurry, but more importantly, it is a design aim of Stupid that it should be clear to the programmer exactly what is happening. Getting clever with the grammar does not aid that process.
Sixthly, keeping your head clear is good! Parsers naturally produce parse trees with great ease, so building a parse tree and then later processing that is the way to go. Trying to do it all in one go rarely works well (single pass compilers are generally rather limited, though Stupid is technically mostly single pass at the moment). Getting used to recursion helps with processing parse trees.
Finally, I had a previous project, CaPerl, where I’d used Parse::Yapp, so I could crib from that to get off the ground rapidly.
Guido van Rossum has never been a big fan of this idea, and he recently unloaded a pile of reasoning as to why. Much of this really boils down to the unsuitability of existing Python implementations as a platform for a capability version of the language, though clearly there are language features that must go, too. There’s more on this point from tav, but perhaps his idea of translating Capability Python into Cajita is a more fruitful course…
Anyway, what intrigued me more than the specifics was this statement from Guido
The only differences are at the library level: you cannot write to the filesystem, you cannot create sockets or pipes, you cannot create threads or processes, and certain built-in modules that would support backdoors have been disabled (in a few cases, only the insecure APIs of a module have been disabled, retaining some useful APIs that are deemed safe). All these are eminently reasonable constraints given the goal of App Engine. And yet almost every one of these restrictions has caused severe pain for some of our users.
Securing App Engine has required a significant use of internal resources, and yet the result is still quite limiting. Now consider that App Engine’s security model is much simpler than that preferred by capability enthusiasts: it’s an all-or-nothing model that pretty much only protects Google from being attacked by rogue developers (though it also helps to prevent developers from attacking each other). Extrapolating, I expect that a serious capability-based Python would require much more effort to secure, and yet would place many more constraints on developers. It would have to have a very attractive “killer feature” to make developers want to use it…
There are two important mistakes in this.
Firstly, capability enthusiasts don’t prefer a security model in the sense that Guido is suggesting; we prefer a way of enforcing a security model. App Engine does this enforcement through layers of sandboxing whereas capability languages do it by not providing the untrusted code with the undesirable capabilities. Of course, a side effect of this approach is that capabilities allow far more subtle security models (e.g. “you can only write this part of the file system” or “you can only write files a user has specifically designated” or “you can create sockets, but only for these destinations”) without much extra work and so capability enthusiasts have a tendency to talk about and think in terms of those subtler models. However, Guido’s all-or-nothing model can be implemented easily with capabilities – we don’t have to be subtle if he doesn’t want us to be!
This fallacy causes the second error – because the security model does not have to be subtler, there’s no particular reason to imagine it should take any longer to implement. Nor need it place many extra constraints on developers (I will concede that it must place some constraints because not all of Python is capability-safe). Developers are really only constrained by capability languages in the intended sense: they can’t do the things we don’t want them to do. If the security models are the same, the constraints will be the same, regardless of whether you use sandboxes or capabilities.
Incidentally, I tried to sell the idea of capabilities to the App Engine team several years ago. Given how far we’ve come with Caja in a year, working on a language that is definitely less suited to capabilities than Python is, I would be very surprised if we could not have done the same for Python by now.
The Native Client team think the point of Native Client is to allow web apps to have access to high speed code without compromising the security of the user. This is certainly a use, but I find the idea of using it to enforce security in other areas quite interesting, too. For example, with Native Client you could make Mark Seaborn’s Plash both portable and more useful – which Mark has been working on. Of course, before this can be relied on we need to know that NaCl is secure, so it is interesting that the team are offering cash for bugs. You could get paid for playing with NaCl!
Never moderate your comments before you’ve woken up. I accidentally marked two perfectly legitimate comments as spam this morning, and it seems WP doesn’t let you get them back…
So, here they are. First from James A. Donald
That is a million fold increase in the number of users of capability systems.
I would like to see a capability vm that runs good old fashioned C++, wherein the only access that code has to the larger world outside the vm is by objects corresponding to data streams – which is in fact very close to he way that vms work right now.
You should look at Native Client.
Secondly, from Julien Couvreur
Congrats! That is great to hear.
In fact, partly spurred on by the existence of Caja, and particularly through the hard work of Mark Miller, Caja’s language expert, the ECMAScript committee has been working on the catchily named “ECMAScript 3.1 Strict” which is pretty much the same language as Caja. I assume that this will, one day, get native support.
A possibility I’ve been musing about that Caja enables is to give gadgets capabilities to sensitive (for example, personal) data which are opaque to the gadgets but nevertheless render appropriately when shown to the user.
This gives rise to some interesting, perhaps non-obvious consequences. One is that a sorted list of these opaque capabilities would itself have to be opaque, otherwise the gadget might be able to deduce things from the order. That is, the capabilities held in the sorted list would have to be unlinkable to the original capabilities (I think that’s the minimum requirement). This is because sort order reveals data – say the capabilities represented age or sexual preference and the gadget knows, for some other reason, what that is for one member of the list. It would then be able to deduce information about people above or below that person in the list.
Interestingly, you could allow the gadget to do arbitrary processing on the contents of the opaque capabilities, so long as it gave you (for example) a piece of code that could be confined only to do processing and no communication. Modulo wall-banging, Caja could make that happen. Although it might initially sound a bit pointless, this would allow the gadget to produce output that could be displayed to the user, despite the gadget itself not being allowed to know that output.
Note that because of covert channels, it should not be thought that this prevents the leakage of sensitive data – to do that, you would have to forbid any processing by the gadget of the secret data. But what this does do is prevent inadvertent leakage of data by (relatively) benign gadgets, whilst allowing them a great deal of flexibility in what they do with that data from the user’s point of view.
Powered by WordPress