SandboxedSafari

When Leopard was released, one of its big selling points was its "sandbox" feature. This garnered a fair bit of attention, as sandboxing is a fairly new feature for consumer operating systems.

A lot of people (myself included) assumed that Leopard's sandbox system would be used for Safari, seeing as how web browser exploits are a tremendously popular attack vector. Unfortunately, Leopard's version of Safari is not sandboxed. In fact, very little of the OS actually is. I don't know the real reason behind this, but I suspect it had to do with the release date pressures. Although Leopard ships with a number of sandbox profiles for things like syslog and ntpd, they are not used in the default config. Pretty much the only things that are sandboxed are mDNSResponder and some xgrid daemons. A quick look at the comments in the existing policies indicate that Leopard's sandbox system (named "seatbelt") is rather... buggy. As it turns out, the comments don't lie -- seatbelt *is* quite buggy, at least as of 10.5.6. Still, it's an extraordinarily powerful (not to mention cool) feature, and it's got a lot of potential to increase the security of Mac OS X.

But enough rambling about seatbelt. I'll make a few pages documenting what I've learned about it -- but until I get around to doing that, let's talk about Safari. Basically, I found that Leopard's sandbox system, buggy though it may be, is sufficiently mature as to allow the development of a seatbelt policy for Safari, albeit with some caveats. SandboxedSafari is my attempt at developing such a policy.

Caveats

Before you get too excited about running a sandboxed browser, I should warn you that this is very much a work-in-progress. The following is a list of flaws, bugs, and vulnerabilities that I've identified in the current version of SandboxedSafari. There may well be others, and you shouldn't count on this software to protect you from a sufficiently-determined attacker (or, for that matter, to remain completely stable...).

  1. No plugin support. I know. That's a big one. Personally it doesn't bother me much -- I loathe Flash, and think that it presents a security risk in and of itself -- but I can't ignore the fact that browser plugins are part of a modern browser's "core functionality". I'm working on implementing support for browser plugins, but at the moment using SandboxedSafari means that you won't be able to use embedded Flash, Java, or QuickTime.
  2. Stability issues. I've been using SandboxedSafari as my primary browser for about two months at the time of this writing, and I think I don't think there are any significant stability issues as is. Still, it does crash slightly more often than Safari itself, so it gets a mention here.
  3. Overly-permissive process-exec rules. I'd like to pass this off as "not my problem", but since most of what I know about seatbelt has been gleaned through poking and prodding at the policy compiler, I may very well have missed something. Regardless, since it appears that 'process-exec' operations must be allowed in order for directory contents to be listed, and since the compiler appears to have a bug regarding the use of regex and literal rules for the same directory path, SandboxedSafari allows 'process-exec' operations for far more things than I'm comfortable with. It's still a lot safer than Safari itself, but I'd defnitely consider this as a "chink in the armor". (Note: if the description of this issue seemed rather murky, you might want to take a look at SandboxedSafari's policy -- it should be clear what I mean. If not, e-mail me and I'll try to think up a better explanation. :D)
  4. No network filtering. I was pleased to see that Leopard's sandbox system contains support for allowing/denying network connections based on their transport protocol, destination address, and port. Unfortunately, it appears that either a) policy support for this feature is broken in current releases of Leopard or b) I'm unable to figure out the correct policy syntax for it. The fact that Leopard's ntpd policy contains the comment "This might be able to be tightened up (I think networ filters were broken pre-WWDC). See named.sb for examples." lends credence to the first explanation. The fact that I'm a Lisp/Scheme newbie lends credence to the second. Either way, the upshot is that SandboxedSafari doesn't restrict outbound connections at all. It *does* prevent Safari from accepting inbound connections, however -- which is a sane move in my opinion, since I can't think of a scenario in which one might want their browser to accept an inbound connection.
  5. No address book integration. I'm pretty sure this is doable, and I intend to see if I can't amend the policy to allow it. I'm divided on whether or not this is a good idea though -- I'd rather not have a browser vulnerability expose my entire contact database.
  6. No keychain integration. Again, I'm pretty confident this can be fixed, but I don't know if it should be. By default the Mac OS X keychain is always unlocked -- so if SandboxedSafari allows keychain access, then a successful exploitation could expose the contents of your keychain. If I do end up writing policy rules to allow this, I'll probably leave them commented out by default.
  7. No HTML 5 audio/video support. Given that HTML 5 isn't really common in the wild yet, this isn't a priority for me. I'll work on figuring out what's needed for video/audio support after I get QuickTime working.
  8. Safari window opens without focus. Not much I can do about that. SandboxedSafari uses a (kinda hackish) launcher. Until I write something better, this is just an unfortunate side-effect of said launcher.

That's about all I can think of off the top of my head. There are a few other potentially-abusable permissions that you can probably spot by going through the policy, but I don't think I've forgotten anything major.

Feedback

If you end up using SandboxedSafari, I'd love your feedback. If it ends up crashing, I'd appreciate it if you could let me know about it so that I can see what broke, and if there's anything I can do to fix it. You can find my contact information here.

Notes

The SandboxedSafari application is just a little launcher that I put together using Platypus and a bash script. It works around a compiler issues -- specifically that regexes slow down policy compilation a lot. To reduce the policy's use of regexes, the username (used in various paths) of the current user is inserted into the policy at run time. The processed policy is stored in a temporary location, and is then used by 'sandbox-exec' when launching the Safari binary. Interestingly, the compiler is very smart about caching compiled policies, and won't recompile a policy if it's the same as an already-compiled one, even if it's located in a different location. The upshot of this is that the policy will only be compiled once per user -- so while the first launch of SandboxedSafari will take a bit of time (and a considerable bit of CPU), subsequent launches should be very quick.

The policy (more correctly the template that's used to generate the policy) is stored in the 'Resources' sub-directory of the SandboxedSafari.app bundle. If you're interested, you can open it up in any text editor and take a look. The comments should explain what each rule does (more or less.)

SandboxedSafari will caused your console logs to be filled with notifications whenever an operation was denied. You should be able to change this by modifying the 'debug' rule in the policy, but IIRC seatbelt may still generate some log spam...

SandboxedSafari will only work on 10.5.x. Tiger has no sandbox system.

The sandbox policy allows for read/write access to the 'Downloads' folder in a user's home directory. It also allows read-only access to a directory named 'Safari Uploads' in the user's home directory. I added this so you can have a read-only "drop box" for files that you wish to upload using Safari, but that you don't want to allow write access to. (Obviously since this directory doesn't exist by default you'll have to create it if you want to use it.)

License

I suppose the Creative Commons license is as good as any, so how about this one?

The license/copyright isn't really the point though... SandboxedSafari is just something that I've had fun tinkering with and that I think might be a useful tool and/or starting point for some people. I'm not a lawyer and I don't know much about copyright, so I don't really know what license to use to accomplish that. If you think that the CC license gets in the way of that goal, please let me know, and I'll try to find a better-suited license.

Download

Version 0.2

You can download SandboxedSafari 0.2 from these locations:

Version 0.1

Not worth using. If you really want it, e-mail me and I'll give you a copy.