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.
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:
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
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" */
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.