Team LiB
Previous Section Next Section

Hack 18. Digitally Sign Content

Content delivered to Firefox can request special privileges from the user.

Normal Firefox content, whether it's HTML, XHTML or XUL, runs inside a sandbox that stops it from doing anything risky, such as modifying files stored on the local disk. This hack explains how to ask the user for permission to escape the sandbox. If permission is given, the content (usually scripts) can do whatever it likes. You can also arrange matters so that the user is never asked for permission [Hack #19] .

2.9.1. Get Oriented on Security Concepts

The design ideas behind granting permission are trust and identity. If the web page content is to have full control over the browser, there must be trust between the browser user and the content creatortwo real, live people. Access to technical features is secondary to this human principle. In the conservative world of security, trust can be assured only if identity can be properly determined. Here are the identity constraints built into Firefox:

  • The browser user always knows whom a content maker requesting trust is.

  • The browser user can always physically track down a content maker that requested trust.

  • The browser user is always free to reject a request for trust.

The Firefox user can drop these constraints if they so choose. When presented with information about a content maker, the user can tell Firefox to trust that content maker in the future. That puts identity information about the content maker in files in the user profile area. Firefox will always validate signed content, but it can do so silently if the user directs it to do so.

Validating signed content is done automatically by Firefox. Making signed content is a task for a web site content creator.

These identity constraints are supported by technologydigital certificates and digital signingand by a special sandbox-breaking API that only works when trust is in place. They also demand some old-fashioned paperwork. A real, live person called a Certificate Authority (CA) is required. Little of that infrastructure is obvious or meaningful to an end user confronted by a permission request, though.

2.9.2. Get Signing Tools

Netscape Security Services (NSS) is a technology that is part of the Mozilla source code used to make Firefox. NSS includes a small, separately downloadable program called signtool. Get it here:

http://ftp.mozilla.org/pub/mozilla.org/security/nss/releases/

signtool can combine content (HTML, JavaScript, XUL, CSS, images, anything) with digital signatures by using certificates. signtool is incompatible with similar systems used in Netscape 4.x, Internet Explorer, and Java. It is good only for Mozilla-based browsers and other software systems that support it. signtool has some compatibility with Java, but a second tool called certtool (http://ftp.mozilla.org/pub/mozilla.org/security/nss/releases/) is also needed.

Signing content is called object signing, which is different than signing a certificate. The result of object signing is a JAR file [Hack #86], which contains both content files and digital signature files.

Signing content is a nuisance for technologists that just want to build something. Mozilla allows signing to occur in two separate ways. You can sign in a test environment, where it is easier to use, or you can sign in a published environment, where it is fully secure.

2.9.3. Sign Content for Test Purposes

In a test environment, two of the three identity requirements can be dropped. The browser user can be kept ignorant of the content maker. The browser user is thus unable to track down that person. That leaves only the requirement that the browser user explicitly grant permission to the content maker. To enable this weaker security arrangement:

  • The content maker uses a special certificate instead of a normal one from a CA.

  • The browser user ensures it's OK for Firefox to accept content signed with that special certificate.

In a test environment, both of these roles are likely to be taken by one developer. To create the special certificate, first create a certificate database. Then, make the special object-signing certificate and put it into the database:

mkdir certs
cd certs
certutil -N -d .
signtool -G '
special
' -p '
password
' -d .

special is the name chosen for the new certificate. The password string should be whatever you typed in when certutil ran. Use single quotes on Linux/Unix to prevent shell reinterpretation.

To tell Firefox it's OK to work with this certificate, use the following preference:

signed.applets.codebase_principle_support /* set to true. Default = false */

Note the security hole: this setting indicates that content signed with any special certificate (from any web site) will be accepted. The name of this preference is an historical artifact from Netscape 4.x. There is no Java or Java applets at work.


You are now ready to sign your content. Suppose it's in the directory content, which is a sibling of the certs directory:

cd ..
signtool -d certs -k '
special
' -p '
password
' -Z result.jar content

The file result.jar is all the signed content. Put it behind the web server and retrieve it with a URL, or with a jar: URL. jar: URLs are normally used for chrome packages [Hack #75], but you can put ordinary web site content in them, too.

2.9.4. Sign Content for Publication

In a production environment, you must have a genuine digital certificate before you start. Suppose your organization's name is Acme, and the certificate comes from the CA Verisign, who gave it this short name: Acme Cert (Verisign). Once that certificate is in a handy certificate database [Hack #17], make your object-signing certificate based on it as follows:

cd certs
signtool -G 'objcert' -k 'Acme Cert (Verisign)' -p '

password
' -d
.

Next, sign your content with it. This is the same as in the test environment, except this time we have a real certificate:

cd ..
signtool -d certs -k 'objcert' -p '

password
' -Z result.jar content

Put the result.jar file on the web server as before. You're ready to go and don't need the special preference.

2.9.5. Do Something with Trusted Content

If you've asked the browser user for trust, you must need it for some reason. There are two things you can do: you can sign an XPI file, and you can write scripts that break normal web scripting rules.

If you sign an XPI file, that file can be installed into Firefox from any web site, provided that the user gives permission. Since an XPI file and JAR file have the same format, the signing procedure is also the same. The web site that delivers the XPI file does not need to be listed as an authoritative source of extensions or patches in this case.

This sample JavaScript script requests all possible permissions and then runs some code that wouldn't work in a normal web page:

function run(  ) {
  // normal permissions to start with
  critical_section(  )
  // normal permissions again
}

// Might be a trusted function, depending on who calls it.
function do_stuff( )
{
  var list = window.Components.classes; // try to access XPCOM
}

function critical_section( ) {
  // ask the user for permissions; should check return value as well

  netscape.security.PrivilegeManager.enablePrivilege(
    "UniversalBrowserRead"        + " " +
    "UniversalXPConnect"          + " " +
    "UniversalPreferencesRead"    + " " +
    "UniversalPreferencesWrite"   + " " +
    "CapabilityPreferencesAccess" + " " +
    "UniversalFileRead"           + " " +
    "myCapability");
 
  window.resizeTo(20,20);   // make current window tiny - requires trust.
  do_stuff( )                // called with trust in place
  
} // permissions will end when this function returns

run( ) // do it

The myCapability option is a custom capability class [Hack #20] . See http://www.mozilla.org/projects/security/components/signed-scripts.html for details on the meaning of all the options.

    Team LiB
    Previous Section Next Section