Sandbox Corners

September 9th, 2011

Apple’s sandboxing technologies make it possible to control at a very fine-grain system level exactly which system resources an application should be allowed to access. It offers control over reading and writing  files, opening  network resources, and much more.

I’m really excited about sandboxing and also really terrified. Apple has given us, thus far, a limiting set of entitlements that don’t quite cover everything that reasonable apps want to do, or even everything that Apple itself has approved as acceptable behavior in the Mac App Store. Yet Apple has made it clear that it wants to see all apps adopt sandboxing, and the writing is on the wall that in particular, participants in the Mac App Store should be prepared for the day when non-sandboxed apps may not be approved for sale in the store.

For us developers looking into sandboxing our own apps, it can be tough to wrap one’s head around exactly what privileges need to be requested. One way to go about it is to sandbox your application with the strictest of controls (basically disallow everything disallowable), and see what breaks. Then you could add back whatever entitlements are necessary to get things working again.

On the other hand, it would be handier to have the system simply tell us what kinds of behaviors our app is engaging in, and what the corresponding entitlements would be to allow it to work even while sandboxed. Thanks to a tracing mechanism in the sandbox, this is in fact possible. Furthermore, you can use a command-line tool to apply arbitrary sandbox profiles to an application without having to modify the application itself.

I defined a handy shortcut in zsh for running an arbitrary app with the “trace” mechanism enabled, to show exactly what the app is accessing, simplify the output, and open it in my default text editor:

function sbx()
{
        echo '(version 1)\n(trace "/tmp/traceout.sb")' > /tmp/tracein.sb
        sandbox-exec -f /tmp/tracein.sb $1
        sandbox-simplify /tmp/traceout.sb > /tmp/tracesimple.sb
        open -t /tmp/tracesimple.sb
}

After you’ve defined this in your .zshrc (other shells, you are on your own!), you can do something like:

sbx /Applications/FastScripts
.app/Contents/MacOS/FastScripts

Then you use whatever features in your app you are concerned about, and quit the app. A text file will open with exquisite details about all the privileged actions your app was permitted to do, which would otherwise be forbidden by the sandbox.  Great, just copy that list of permissions into your sandbox entitlements plist, and we’re done. Right? Not quite.

The rules generated by the trace are very precise and may not be sufficient to cover your app’s behavior in practice. For example, if I open FastScripts, my scripting utility, and run a single AppleScript that controls the terminal, the resulting permissions trace reveals a sandbox rule that would allow that behavior to happen:

(allow appleevent-send
       (appleevent-destination "com.apple.terminal"))

That’s well and good for a utility that only ever needs to send events to the Terminal, but of course FastScripts is a general purpose scripting application that needs to send events “wherever the heck the user wants to send them.” Currently, Apple doesn’t offer a sandbox entitlement for this broad behavior, so it is not possible to sandbox FastScripts.

I think that Apple would have a lot more developer enthusiasm for this feature if it wasn’t so clear to many of us that our apps will be forced to lose features in order to adopt sandboxing. And while users may be happy about the prospects of improved security with the sandbox, I think there will be less excitement about the diminished functionality of apps whose features don’t fit nicely into the sandbox confines.

Developers and power-users can use the sandbox command-line tools now to get a good sense for what will or will not work down the road if sandboxing, with the current set of entitlements, is enforced by Apple for a large number of 3rd party applications. There is some documentation for these tools in e.g. “man sandbox-exec”, but the documentation is pretty minimal. If you want to read more, check out this useful document, which aims to give a better understanding of the sandbox, entitlement profiles, and how to use the command-line tools.

 

6 Responses to “Sandbox Corners”

  1. Ted Wise Says:

    Sandboxing doesn’t really work for applications that allow scripting to control the system. And, as you’ve stated, some applications have to cut features to fit into the existing sandbox privileges. Look at how 1Password was modified to fit into the Mac App Store. In some cases, it requires re-thinking, 1Password switched from installing browser plug-ins to bringing up a web page that a user could download the plug-ins from. Less convenient, but works in the sandbox model.

    But the reality is that some applications, especially applications that need to reach into the system or control elements that Apple doesn’t allow or support to be controlled, won’t be able to be sandboxed. But then, most of those applications weren’t suitable for inclusion in the Mac App Store anyway.

    It’s a tradeoff that most end-users won’t even know is being made but will appreciate as increased security. But it’s annoying to developers who no longer have automatic privilege escalation when editing locked files in BBEdit.

  2. elasticthreads Says:

    Thank you for the truly helpful post.

    I hope Apple figures out a reasonable way to allow robust AppleScript events in sandboxed apps. Seemed like the creation, and continuing support, of ApplescriptObjC was a sign that Apple would continue to promote and welcome cross app scripting and communication on OS X.

    I’d be really interested to know (and maybe the developer of FastScripts might know the answer) what security vulnerabilities exist within AppleEvents and cross-application communication. Obviously “Do shell script…”, “tell application “Finder” to erase…”, “tell application “System Events…” all have a lot more power, and danger, than a sandboxed app “should” have. Is it as simple as that?

    What are your thoughts on how much Apple should limit AppleScript in sandboxed apps?

  3. TimeDwarf Says:

    I suspect that there will be further access to complex and core privileges with additional tiers of code signing. The vetting process for advanced access will likely be of a standard equivalent to acquiring bonded status as a business. You would then stand out as liable for misuse of the extra privileges.

    I’d be very interested to hear your thoughts about the code signing features and their effects& possible chillling of enthusiasm upon new and younger developers.

  4. Dave Reed Says:

    Has Apple provided any more details about sandboxing than a “November deadline”? I’ve yet to see anything more official and that date is drawing near. I think I’ve got a sample app working with the XPC functionality I need for my app, but I haven’t actually integrated it into my app yet.

  5. Karsten Says:

    Thanks so much for that post! i’ve been looking into this whole sandbox stuff just some days ago and found it absolutely frustrating without the trace function. Your script really takes away the pain!!

    here’s also the bash version (worked for me)

    function sbx()
    {
    echo ‘(version 1)
    (trace “/tmp/traceout.sb”)’ > /tmp/tracein.sb
    sandbox-exec -f /tmp/tracein.sb $1
    sandbox-simplify /tmp/traceout.sb > /tmp/tracesimple.sb
    open -t /tmp/tracesimple.sb
    }

    Karsten

  6. Derek Says:

    Useful idea, but it doesn’t always seem to work.

    Using 10.6.8 with latest updates, I get errors.
    Maybe the ‘trace’ facility only works on 10.7?

    derek$ sandbox-exec -f /tmp/tracein.sb /Applications/TextEdit.app/Contents/MacOS/TextEdit
    2011-11-05 11:40:43.956 TextEdit[7141:907] No Info.plist file in application bundle or no NSPrincipalClass in the Info.plist file, exiting

    whereas I can start Textedit quite happily as:

    derek$ /Applications/TextEdit.app/Contents/MacOS/TextEdit

    Similarly for an app of my own, I see:

    derek$ sandbox-exec -f /tmp/tracein.sb ./Zz.app/Contents/MacOS/Zz
    Bringing front
    2011-11-05 11:43:00.267 Zz[7142:907] appWillFL
    2011-11-05 11:43:00.318 Zz[7142:907] *** Assertion failure in _NSLocateKitBundle(), /SourceCache/AppKit/AppKit-1038.36/AppKit.subproj/NSApplication.m:6482
    2011-11-05 11:43:00.319 Zz[7142:907] Can’t find AppKit resources.
    2011-11-05 11:43:00.368 Zz[7142:907] appWillBA
    2011-11-05 11:43:00.370 Zz[7142:907] appDidBA
    2011-11-05 11:43:04.729 Zz[7142:907] appWillRA
    2011-11-05 11:43:04.731 Zz[7142:907] appDidRA

    Suggesting that even with just ‘trace’ there are some filesystem accesses which fail.

Comments are closed.

Follow the Conversation

Stay up-to-date by subscribing to the Comments RSS Feed for this entry.