logoalt Hacker News

Earw0rmlast Monday at 8:15 AM1 replyview on HN

IMO what's needed is less per-app sandboxing, and more per-context.

Think user accounts but for task classes.

If I'm doing development work, I want to be able to chain together a Frankenstein of apps, toolchain, API services and so on, with full access to everything else in that specific context.

But that doesn't need visibility of my email, my banking and accounting software should have visibility to/from neither, and random shareware apps, games and movies should run, like you say, with a browser tab level of permission.

Making this work in practice while keeping performance maximised is harder than it sounds, preventing leaks via buffers or timing attacks of one sort or another (if apps can take screenshots, game over).. for now I use user accounts, but this is becoming less convenient as the major desktop OS and browser vendors try to force tying user accounts to a specific online identity.


Replies

josephglast Monday at 8:44 AM

> IMO what's needed is less per-app sandboxing, and more per-context.

I think you could do this with capabilities!

The current model makes of security implicit, where an application can make any syscall it wants and its up to the OS to (somehow) figure out if the request is valid or not. Capabilities - on the other hand - restrict access of a resource to the bearer of a certain token. The OS knows that by invoking capability X, the bearer can make requests to a certain resource / account / file / whatever. (Think of it like unix file descriptors. You just call write(1, ...) and the OS knows what file you're writing to, and what your access to that file is.)

There's lots of ways to use capabilities to build the sort of frankenstein app you're talking about using caps. Eg, you could have a supervisor task (maybe the desktop or a script or something) that has a capability for everything the user cares about. It can create sub-capabilities which just have access to specific network ports / files / accounts / whatever. It launches subprocesses and hands the right capabilities to the right sub processes. The sub processes don't even need to know what the capability they were given connects to. They just need to know - for example - that reading from the capability gives it the data it expects to receive. Then you can do all the routing & configuration from the supervisor task.

Because all the sub processes only have the specific capabilities that were passed to them, the security surface area is automatically minimised.

SeL4 shows that you can do this without losing much performance. (In SeL4, the IPC overhead is tiny.) But as I said upthread, I'm sure there's also ways to design our programming languages to allow within-process isolation. So, for example, you can call the leftpad package without giving it capabilities held by other parts of the same program.

Capabilities can also make it easy to virtualise filesystems, the network, and so on. Or to do interdiction - and snoop on the messages being sent. Its easy because you can just make virtual network / filesystem / whatever capabilities and pass those to subprocesses.