Team LiB
Previous Section Next Section

Hack 20. Restrict Script Behavior with Policies

Internet Explorer has security zones. Firefox has capability classes instead.

When web pages load into Firefox, they stay inside a sandbox where they can't compromise the user's security. All unsigned web pages are displayed securely. Such pages still have a lot of latitude, though. Scripts in web pages can do all sorts of things. This hack explains how to change what scripts are allowed to do. Use of policies is extreme fine-tuning of Firefox.

2.11.1. Capabilities and Policies

You can control script access to features of Firefox by defining access rules and collecting those rules together into a named policy. You can define more than one policy. If a Firefox feature such as window.open() is put together with a particular kind of access, the combination is called a capability. Each access rule allows or denies one or more capabilities. Each policy therefore represents a set of capabilities.

Every method and property of every browser or document object exposed to JavaScript by a DOM standard can be controlled with a capability.

Ordinary policies automatically apply to ordinary web pages. Before a script can use a built-in feature of Firefox, it has to get through all the existing policies unscathed. Firefox provides two policies automatically: one default policy, named default, and one wildcard policy, named *. The existing default policy applies everywhere and is the normal state of affairs. The wildcard policy does nothing, but it is a convenient place to override default policies, if that is required. Policies are typically used differently, depending on the kind of web page to which they are applied:


For ordinary web pages

Policies usually lessen rather than expand capabilities. Such pages don't need to request anything.


For signed web pages

Policies usually grant extra access. Such pages need to explicitly request the policies that will provide that access [Hack #17] .

Firefox policies are stored in the preference system as simple preferences. You can add more default policies, enhance the wildcard policy, or make your own policy.

2.11.2. Make a Policy

First, register the new policy or policies. Set this preference to whatever policy names sound meaningful:

capability.policy.policynames         /* eg "nohistory lax imageswap" */

Set this preference instead if you want the policies to be default policies:

capability.policy.default_policynames /* eg "nohistory lax imageswap" */

Once the policies are registered, assign them to web sites or to whole URI schemes. The default policy applies to all web sites. Assign the sample nohistory policy like this:

capability.policy.nohistory.origins   /* eg "https: http://www.x.org" */

In this example, every https: URL and every URL on the X-Consortium's web site will have the nohistory policy applied to scripts run inside its web pages.

Finally, add the access rules to the policy. In this example, we prevent scripts from calling window.history.back() and from looking at or setting the document.location.href property. The following example is incomplete, because there are many features that need to be blocked if scripting of history is to be completely prevented:

capability.policy.nohistory.History.back       /* set to "NoAccess" */
capability.policy.nohistory.Location.href.get  /* set to "NoAccess" */
capability.policy.nohistory.Location.href.set  /* set to "NoAccess" */

NoAccess is the only practical value for policies aimed at ordinary web pages. The first preference is suitable for a JavaScript host object method. The second and third preferences are for a JavaScript host object property. The object names used in these preferences are Mozilla XPIDL interface names with the prefix nsIDOM ripped away. So, History is really nsIDOMHistory.

To see if this works, just load any web page with a piece of JavaScript like this:

alert(window.location.href);

2.11.3. Using a Policy from a Signed Script

Capabilities for signed scripts can be set to NoAccess, SameOrigin, or AllAccess. These are combined with an access type, such as the presupplied access type UniversalXPConnect [Hack #18] . Instead of using these standard access types, use the custom policy name.

    Team LiB
    Previous Section Next Section