Configurable Security Policies
Mozilla's configurable security policies allow users to set up security policies for the browser, and also have different security policies for different Internet sites. The ideas for configurable security policies come from a number of sources. Bell Labs researchers Vinod Anupam and Alain Mayer have written papers and contributed code to Mozilla. The infamous bug 858 serves as a wish list for this sort of functionality. The code for this is called CAPS (capabilities). Finally, IE's zones employ some of this idea.
N.B. As of Mozilla 0.9.9, a "policynames" line is required in order to create zone policies. See below for details.
Suppose you're annoyed by pop-up advertisements and want to prevent all web pages from opening new browser windows. You can do this by adding the following line to your Mozilla user preferences file (user.js):
noAccess means that web pages can
not access the
open property of any object of type
If a web site tries to open a new window using
open()), the attempt will fail. The security manager will throw a
web page catches the exception, the script will stop and an error message
default policy is special; it applies to all sites.
You can also set policies that apply to specific sites or groups of sites,
overriding the default. For example, if you wanted to restrict www.evil.org
and www.annoying.com from creating dialog windows,
you could use the following code:
user_pref("capability.policy.policynames", "strict"); user_pref("capability.policy.strict.sites", "http://www.evil.org http://www.annoying.com"); user_pref("capability.policy.strict.Window.alert", "noAccess"); user_pref("capability.policy.strict.Window.confirm", "noAccess"); user_pref("capability.policy.strict.Window.prompt", "noAccess");
The first line defines the name of the policy or policies you want to create,
in this case
"strict". If you define more than one policy, list them all
on the same line, like so:
user_pref("capability.policy.policynames", "strict, shoppingsites, ");
The preference "
capability.policy.strict.sites" defines the web
sites to which the
strict policy is applied. The value of that
preference is a list of sites (protocol and hostname only), separated by
spaces. The final three lines define the strict policy. For these sites,
the example above will disallow access to
Note that since we haven't defined whether sites under the
can open new windows with
window.open(), the default policy still applies.
Suppose we've also discovered that in blocking access to
we've prevented a script on www.usefulsite.net from working. We can allow this
page to bypass the window.open restriction by setting the
back to its default value,
user_pref("capability.policy.policynames", "trustable"); user_pref("capability.policy.trustable.sites", "http://www.usefulsite.net"); user_pref("capability.policy.trustable.Window.open", "sameOrigin");
The name of the policy can be anything you want; we used
trustable in this example, but you could name it
mypolicy or anything else.
There are three special security levels:
noAccess: web sites can never access this property or call this function.
sameOrigin(default): web sites can access this property, but only for pages on the same site. See this document for an explanation of how Mozilla determines whether two pages have the same origin.
allAccess: a web site can access this property within the same site and on any other site.
If the security level is not one of the three above, it is treated as a privilege name, and a script can access it only if the script is signed and the user grants the privilege to the script through a dialog.
You can specify a policy that applies only to reading a property, or only
to changing its value, by adding
.set after the property name.
This allows you to specify one policy for reading a property and another for
changing its value. See below for some examples that block pages
from setting values but not from reading them.
Class.property.set to the same level is
equivalent to setting
Class.property to that level. Don't use
set after the name of a function (such as
the concept of "get" and "set" applies only to properties which are not functions
Figuring out the correct object name to use is sometimes tricky. For example,
suppose you want to prevent a web page from submitting a form for you, but you don't
know the class name for a form element. The easiest way is to find out is to write
a script that converts the object into a string. If you go to a page with a form
document.forms is an
[xpconnect wrapped HTMLFormElement].
HTMLFormElement is the name of the class, so you can set
noAccess to prevent web pages from
submitting forms using
Some elements, such as
HTMLAnchorElement, have special toString functions
that prevent you from finding their class name easily. If you type
you will see the URL of the first link instead of its class name.
The way to get around this problem is to use the default
toString function on the object document.links, like so:
When blocking access to properties, it is important to note that there is more than
one way to access some properties, such as attributes of HTML elements. For example,
suppose a user wants to prevent scripts from
www.evil.org from accessing the
href attribute of HTML anchor tags
(<A HREF="...">). The following
prefs are not sufficient:
user_pref("capability.policy.policynames", "nohrefs"); user_pref("capability.policy.nohrefs.sites", "http://www.evil.org"); user_pref("capability.policy.nohrefs.HTMLAnchorElement.href", "noAccess");
While these prefs will prevent a script on
www.evil.org from accessing
document.links.href, the script can access the very same information
using the DOM 2 syntax
document.links.getAttribute("href"). The following prefs will completely
block access to the href attribute:
user_pref("capability.policy.policynames", "nohrefs"); user_pref("capability.policy.nohrefs.sites", "http://www.evil.org"); user_pref("capability.policy.nohrefs.HTMLAnchorElement.href", "noAccess"); user_pref("capability.policy.nohrefs.HTMLAnchorElement.attributes", "noAccess"); user_pref("capability.policy.nohrefs.HTMLAnchorElement.getAttribute", noAccess"); user_pref("capability.policy.nohrefs.HTMLAnchorElement.getAttributeNS", "noAccess");
As a general rule, to block access to an attribute, you must also block the
attributes property and the
- A policy consists of a policynames line, a sites line,
and one or more policy lines.
The sites line must be omitted for the
defaultpolicy, but it must be present for all others.
- The policynames line specifies the names of all the policies you want to define.
There should be only one policynames line, no matter how many policies you define. It
has this format:
user_pref("capability.policy.policynames", "<list of policy names>");where <list of policy names> is a list of the policy names you want to define, separated by commas and/or spaces.
- The sites line has this format:
user_pref("capability.policy.<policy name>.sites","<URL list>");
- <policy name> is any combination of letters and numbers, starting with a letter.
- "<URL list> is a list of URLs separated by spaces. Each URL in the list can
either be of the form
protocol:, which will apply the policy to all URLs with the given protocol (such as http:), or
protocol://hostwhich will apply to a particular host (for example, http://www.annoyingsite.myisp.com). Don't include the path portion of the URL (the / after the host name or anything after it).
- A policy line has this format:
user_pref("capability.policy.<policy name>.<class name>.<property name>","allAccess | noAccess | sameOrigin | <capability name>");
- <policy name> must be the same as the policy name on the sites line.
- The pref values (
allAccess, etc.) are described above.
The special property
either globally, using the
default policy, or for a group of sites, using a site policy.
For this special policy, the value of the preference must be
execution at site1.com and site2.com:
Note that only values of
"noAccess" will work for the
"sameOrigin" or any other
string in this case. Also note that this preference:
capability.policy prefs, including
user_pref("capability.policy.default.Window.innerWidth.set", "noAccess"); user_pref("capability.policy.default.Window.innerHeight.set", "noAccess"); user_pref("capability.policy.default.Window.outerWidth.set", "noAccess"); user_pref("capability.policy.default.Window.outerHeight.set", "noAccess"); user_pref("capability.policy.default.Window.sizeToContent", "noAccess"); user_pref("capability.policy.default.Window.resizeTo", "noAccess"); user_pref("capability.policy.default.Window.resizeBy", "noAccess");
user_pref("capability.policy.default.Window.screenX.set", "noAccess"); user_pref("capability.policy.default.Window.screenY.set", "noAccess"); user_pref("capability.policy.default.Window.moveTo", "noAccess"); user_pref("capability.policy.default.Window.moveBy", "noAccess");
(Note: these lines don't block all of the ways a web page might find your screen reslution; they only block the most common ones. They don't prevent a web page from finding out how big its window is.)
user_pref("capability.policy.default.Screen.top", "noAccess"); user_pref("capability.policy.default.Screen.left", "noAccess"); user_pref("capability.policy.default.Screen.width", "noAccess"); user_pref("capability.policy.default.Screen.height", "noAccess"); user_pref("capability.policy.default.Screen.pixelDepth", "noAccess"); user_pref("capability.policy.default.Screen.colorDepth", "noAccess"); user_pref("capability.policy.default.Screen.availWidth", "noAccess"); user_pref("capability.policy.default.Screen.availHeight", "noAccess"); user_pref("capability.policy.default.Screen.availLeft", "noAccess"); user_pref("capability.policy.default.Screen.availTop", "noAccess");
Some web pages create "blind links" by changing the status bar text when you hover over the link, preventing the link address from being show in the status bar. This line will turn most blind links into normal links.