From MozillaWiki
Jump to: navigation, search

XPCNativeWrapper and how it affects YOU

What is it?

XPCNativeWrapper is a special object that is substituted for real objects in situations that could be abused by 'untrusted' code. Exactly what is trusted and untrusted is explained below.

This wrapper protects the caller by deciding whether it should be allowed to 'see' (and thus access) anything not originally part of the object (as defined by IDL) - i.e. anything that was added or overriden by JavaScript or another scripting language.

What is trusted?

Scripts, objects and windows all have their own rules for defining if they are trusted, and how trust is propagated throughout the system. These rules are described below.

What designates a trusted script?

Scripts are trusted or untrusted based on their URI. All scripts are untrusted unless they are specifically marked trusted. A script will be marked trusted if the URI starts with a known trusted 'prefix'. The prefixes are currently all set by the Chrome Registry, which is responsible for handling URIs in the 'chrome' scheme.

By default, all content packages are trusted. This means, all URIs that start "chrome://<package name>/content/" (for any package) are trusted. Individual packages can override this using a flag in their chrome manifest file.

What designates a trusted object?

Native objects (e.g. DOM objects) are also either trusted or untrusted. The interaction between scripts and objects depends on the trusted status of both parties.

An object is trusted if any of the following hold:

  1. Its parent is a trusted object.
  2. It is the root scope object for a JavaScript component.
  3. It is the window object for a window that is designated trusted.

FIXME: How the contruction of objects at run-time interacts with this I still don't follow

Bug 306108, comment 18 talks about two bits, and also about the URI for markup, which is not mentioned anywhere else.

What designates a trusted window?

Windows get their trust from their container, but with special conditions. A window is trusted if any of the following holds:

  1. It is a top-level window (e.g. <xul:window>, <xul:dialog>, or some URI passed to the -chrome command-line flag).
  2. Its parent is trusted, and one of the following three options holds:
    1. It is not loaded in a <xul:iframe> or <xul:browser>.
    2. The <xul:iframe> or <xul:browser> loading it doesn't have a "type" attribute.
    3. The value of the "type" attribute of the <xul:iframe> or <xul:browser> loading it is not "content" and does not start with "content-".

Note that whether a window is trusted does not depend on the URI loaded in the window. So for example, the following would create trusted windows when used inside a document whose window is already trusted:

  • <xul:browser>
  • <xul:browser type="chrome">
  • <xul:browser type="rabid_dog">
  • <xul:iframe type="foofy">
  • <html:iframe>
  • <html:iframe type="content">

The following would not create a trusted window:

  • <xul:browser type="content">
  • <xul:iframe type="content-primary">

Further note that any subframe of an untrusted window is automatically untruested.

What happens when a script accesses an object?

The table below describes what happens when a script accesses an object, and how the wrapper is involved.

Script Object Effects
Trusted Trusted No wrapper is created, and thereforce the script gets full access to the object.
Trusted Untrusted A deep wrapper is created, and only properties defined in IDL are available, and always refer to the original native implementations, never any overrides from scripts.
Untrusted Trusted This should be impossible. ;-)
Untrusted Untrusted No wrapper is created, just as in the trusted/trusted case.

What if I want the untrusted stuff?

In the case that a trusted script is accessing an untrusted object, all the extra properties, and any overriden ones, set by scripts will be unavailable. This is very safe, and protects code from abusive and malicious scripts.

However, sometimes explicit access to the untrusted object is desired. All wrapped objects have a special property, wrappedJSObject, which returns the real object behind the wrapper. Use this with caution, as this removes all the protection afforded by the wrapper.