Configuring Mozilla
What are 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. Finally, IE's zones employ some of this idea.
This document is aimed at programmers familiar with JavaScript.
Setting Global Policies
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 preferences file (prefs.js):
user_pref("capability.policy.default.Window.open", "noAccess");
Setting Window.open to noAccess means that web pages can not access the open property of any object of type Window. If a web site tries to open a new window using window.open() (or open()), the attempt will fail. The security manager will throw a JavaScript exception, preventing the function from being called. Unless the web page catches the exception, the script will stop and an error message will appear on the JavaScript console (Tasks->Tools->JavaScript Console).
Zone Policies
The 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.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 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 window.alert(), window.confirm(), and window.prompt().
Note that since we haven't defined whether sites under the strict policy can open new windows with window.open(), the default policy still applies.
Suppose we've also discovered that in blocking access to window.open(), 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 Window.open policy back to its default value, sameOrigin:
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 strict and trustable in this example, but you could name it blacklist or mypolicy or anything else. Be sure the policy name on the sites line matches the name on the other lines which define the policy for those sites.
Security Levels
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.
Get and Set
You can specify a policy that applies only to reading a property, or only to changing its value, by adding .get or .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.
Setting Class.property.get and Class.property.set to the same level is equivalent to setting Class.property to that level. Calling a function is always considered a get.
Figuring out Object Names
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 and type javascript:alert(document.forms[0]) into the location bar, you'll see that document.forms[0] is an [xpconnect wrapped HTMLFormElement]. HTMLFormElement is the name of the class, so you can set HTMLFormElement.submit to noAccess to prevent web pages from submitting forms using form.submit.
Some elements, such as HTMLAnchorElement, have special toString functions that prevent you from finding their class name easily. If you type javascript:alert(document.links[0]) in the location bar, 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[0], like so: javascript:alert(window.toString.apply(document.links[0])).
The Complete Preferences Syntax
Here's a more formal statement of the syntax for JavaScript security policies:
- A policy consists of a sites line and one or more policy lines. The sites line must be omitted for the default policy, but it must be present for all others.
- The sites line has this format:
user_pref("capability.policy..sites"," "); is any combination of letters and numbers, starting with a letter. - "
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://host which 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.. . ","allAccess | noAccess | sameOrigin | "); must be the same as the policy name on the sites line. - The pref values (allAccess, etc.) are described above.
Disabling All Javascript for a Site
The special property javascript.enabled can be used to disable JavaScript execution, either globally, using the default policy, or for a group of sites, using a site policy. For this special property, the value on the policy line should be true or false instead of allAccess, etc. The following example disables all JavaScript execution at site1.com and site2.com:
user_pref("capability.policy.nojs.sites", "http://site1.com http://site2.com"); user_pref("capability.policy.nojs.javascript.enabled", "noAccess");
This example disables JavaScript execution at all sites except goodsite.com:
user_pref("capability.policy.default.javascript.enabled", "noAccess"); user_pref("capability.policy.jsok.sites", "http://goodsite.com"); user_pref("capability.policy.jsok.javascript.enabled", "allAccess");
Note that only values of "allAccess" or "noAccess" will work for the javascript.enabled policy prefs. Don't use "sameOrigin" or any other string in this case. Also note that this preference:
user_pref("javascript.enabled", false);
overrides all capability.policy prefs, including capability.policy.default.javascript.enabled, for all sites.
Additional Examples
Prevent web pages from resizing browser windows
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");
Prevent web pages from moving browser windows
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");
Prevent web pages from finding the your screen resolution and color settings
(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");
Prevent web pages from changing the text in the status bar
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.
user_pref("capability.policy.default.Window.status", "noAccess");
User Interface
We still have no user interface for configuring security policies. In the future, we hope to have a panel in preferences that allows the user to set policies without having to manually edit prefs.js or know JavaScript. This may be the hardest part of the feature to implement. See bug 38966.