A Security Model for Ubiquity

We discussed at the first Ubiquity planning meeting that we need to come up with and implement a security model for the next release, so I thought I’d write down a few thoughts I’ve been having about it. I don’t consider myself a security expert by any stretch of the imagination, though, so any suggestions or corrections are more than welcome.

Firstly, as noted in the meeting notes, the notion of a security model being discussed here is separate from, but supporting of, the kind of social “web of trust” based model that I’ve written about before. Being able to easily communicate to someone with technical expertise that a piece of functionality will only be able to have a certain level of access to their system can be an excellent aid in determining whether they want to risk trying it out, and this in turn can affect whether they ultimately recommend it to other less technical members of their trust network.

Looking at the current state of mechanisms that allow people to “remix the web”, there appear to be a number of security models out there:

  • Bookmarklets are run in the context of the web page that they’re activated on; they can’t do anything that the web page they’re running on can’t. While this means that they won’t be able to access the filesystem or anything, it does mean that they can potentially abuse any sensitive information contained on the webpage itself. In Firefox security parlance, a script with this kind of limited access is referred to as “running with content privileges.”
  • Greasemonkey Scripts, to my understanding, run in a sandboxed environment that has full access to the web page they operate on via XPCNativeWrappers, as well as special access to more limited functionality via GM_* functions. Consequently, a malicious GreaseMonkey script could do more than a malicious Bookmarklet, but not nearly as much damage as a malicious client-side executable.
  • Firefox Extensions are not sandboxed in any way; as such, they have the same privileges as the Firefox process that contains them, which usually means that they can do whatever they want to your computer. In Firefox security parlance, this is referred to as “running with chrome privileges.”

At present, while Ubiquity command feeds are technically sandboxed via Components.utils.Sandbox instances, the sandboxes are currently initialized using a security principal that gives them chrome privileges. On top of that, even if they were initialized with a more limited principal providing only content privileges, they’re currently accessed insecurely. Both of these aren’t very hard to change, though; the primary challenge will be determining a security model that’s best for Ubiquity’s needs.

One solution may be to have each command feed choose from one of many security model selections. For instance, a command feed’s metadata could specify one of the following security levels:

  • Greater Chrome command feeds execute with full chrome privileges (i.e., how command feeds are currently executed).
  • Lesser Chrome command feeds execute with Greasemonkey-like privileges, whereby they have secure access to untrusted content and limited access to chrome functionality, such as cross-site XHR’s. It’s possible that extra metadata could specify exactly what subset of chrome features the command feed has; for instance, one command feed might request only that it have the additional access to make XHR requests to two particular domains. Care, however, must be taken to ensure that this “security manifest” isn’t so complex that it makes understanding the security implications of a command script difficult and error-prone.
  • Greater Content command feeds execute with Bookmarklet-like privileges.
  • Lesser Content command feeds only have the ability to examine the current selection and replace it. This could be useful for commands like “uppercase.”

For the sake of experimentation and exploration, it may even be useful to make security models “pluggable”, so that anyone can write their own security model, which can then be used to limit the privileges of any command feed that runs under it.

As a place to start, I’ve created a new safebox.js JS module in the Ubiquity repository that provides a safe interface to communicate with a Components.utils.Sandbox running untrusted code in xpcshell or an XULRunner application (e.g., Firefox or Thunderbird). All data going into and out of the sandbox is marshalled using JSON, and all communication is synchronous. Sample unit test code can currently be found in safebox_tests.js. I’d also like to thank Blake Kaplan for explaining some of the underpinnings of the Spidermonkey and XPConnect security models to me, as well as assisting in the debugging of some strange XPCSafeJSObjectWrapper behavior under xpcshell.

If anyone has any feedback on what’s been described here, I’d love to read it.

6 Responses to “A Security Model for Ubiquity”

  1. dennis Says:

    I use this exported function for wrapping everything that comes out of my Sandbox (which has a content principal). After reading MDC extensively i believe this protects me from the famous (fixed) GreaseMonkey hack. Off course you cannot rely on the behavior of the objects coming out of a sandbox but they won’t be able to execute any code in the privileged context.

    var SJSOW = function SJSOW(unsafe) {
    switch (typeof unsafe) {
    case “number” :
    case “string” :
    case “boolean” :
    case “undefined”:
    return unsafe;
    case “function” :
    case “object” : {
    try {
    // it’s a wrapped XPCOM create deep explicit XPCNativeWrapper
    return new XPCNativeWrapper(unsafe);
    } catch (e) {
    // it’s an Object, Array, Date .. wrap in XPCSafeJSObjectWrapper
    return new XPCSafeJSObjectWrapper(unsafe);
    }
    }
    }
    };

    // Now wrap each argument or return value coming out of the sandbox.
    var unsafe = evalInSandbox(code, sandbox);
    var safe = SJSOW(unsafe);

  2. Josh Says:

    http://en.wikipedia.org/wiki/Capability-based_security
    And http://www.eros-os.org/pipermail/cap-talk/2003-March/001133.html

  3. Jason Orendorff Says:

    I dunno. If a malicious command just has Greater Content access, it has plenty enough power to screw me over, right? How do you present that to users?

    “Note: When you use this command, it can modify the content and behavior of the web page you’re looking at. It can perform actions on that web site on your behalf. Worst case, if you use this command while at your bank’s web site, the command could steal all your money.”

    (Am I wrong about what “Greater Content” means?)

    I’m all for defense in depth, but this layer seems *so* weak. It seems like it might instill a false sense of security; or it might just be a bunch of work for not much benefit.

    We need either a security level that actually provides the right amount of power (“Lesser Content” offers too little; “Greater Content” far too much) or a web of trust with effective blacklisting.

  4. Jason Orendorff Says:

    Or maybe the UI should treat Ubiquity commands exactly like add-ons.

  5. Jethro Larson Says:

    It’s a cool idea. I’d like to keep the addons that use filesystem privileges separate from those that just have basic js abilities. My first plug-in falls in the “lesser content” category and I’d like to be able to say, “hey, I’m not doing anything fishy”, in a believable fashion.

  6. Ubiquity 0.2 Preview Release: Feed Plugins! at Toolness Says:

    [...] I’ve written about before, one of the big issues confronting users of Ubiquity and other generative tools like [...]