Feb 11

xpcnativewrappers=no going away

Category: Uncategorized

Way back in 2005, jst, brendan, and bz combined to implement XPCNativeWrappers (or, as I’ll refer to them, XPCNWs). XPCNWs have the somewhat bizarre behavior that they incompatibly change the view of an object from an extension’s perspective. For example, an extension that grabs a content window’s “window” object and tries to call a function on it that is not part of the DOM, would work before XPCNWs, but not after.

Not having concrete data on how many extensions would be affected by such a change and erring on the side of caution, we implemented a way to opt out of XPCNWs. Basically, if your extension broke because of XPCNWs you could ask Gecko to give you the old, insecure, behavior. The intent at the time was to let authors flip the switch off, then go back to their extension and fix things until they could turn on XPCNW support.

Now, in order to support a more secure and easier to use platform, it is necessary to remove support for xpcnativewrappers=no. This will mean some work on extension authors’ parts:

  • If your extension relies on xpcnativewrappers=no, your extension will stop working correctly when bug 523994 lands.
  • In order to fix it, you should identify the parts of your extension that require direct access to content objects. This should be limited to three cases:
    1. If your extension depends on XBL bindings attached to content objects (namely, being able to call functions or get and set properties created by the XBL binding) then you will need to use the .wrappedJSObject of the XPCNW.
    2. If you need to call functions or access properties defined by the content page (for example, if you wrote an extension to add a delete button to gmail and there’s a window.delete() function defined somewhere).
    3. See The devmo page on XPCNativeWrappers for more.
  • Note that if all you do with content objects is use DOM methods, then everything should simply continue to work (and you shouldn’t be using xpcnativewrappers=no anyway)!

I’ll write a second post soon to describe the what and why of XPCNWs and .wrappedJSObject.

4 comments

4 Comments so far

  1. Paul February 11th, 2010 10:33 pm

    Can you please provide the workaround for the common use of xpcnativewrappers=no (the gmail example for instance)?

  2. Paul February 11th, 2010 10:34 pm

    It’s a huge change for extension developers, don’t forget to make sure it’s going to be documented (dev-doc-needed).

    Thanks 🙂

  3. mrbkap February 12th, 2010 1:53 am

    @Paul, I’ll include such an example in my next post. The short of it is that by using .wrappedJSObject (or, the newly introduced on trunk XPCNativeWrapper.unwrap(maybeNativeWrapper)) you can access the underlying objects.

    My hope (and from what I saw from DOMI, this was true) is that there are relatively few objects that people need to explicitly unwrap, or there are good “choke points” in extension code where they can unwrap and deal with less safe objects. For example, if you have some in |b|, and you know that the page in |b| sticks some useful data in an object in a global variable, you might be able to say:

    data = b.contentWindow // XPCNativeWrapper
    .wrappedJSObject // “Raw” object
    .state // Still “raw” (no need for another .wrappedJSObject)
    .usefulInfo // Same as above.

    My mental model of this stuff is that there is some object graph, starting at the window (global object) and extending down, through the DOM and the objects created via ‘new …’ by the web page’s scripts. Most extensions (I hope!) only need the “raw” view of a relatively small portion of the web page’s object graph, and they can enter into that view via .wrappedJSObject to expose a subgraph. As I’ll also explain in my post tomorrow, this has the advantage that when you’re looking for potential security problems in your code, .wrappedJSObject jumps out as a red flag for review (oops, this is where the web page might start lying to me!).

    Make sense?

  4. Paul February 25th, 2010 10:25 am

    Do you have a bug number?