[Previous] [Next] [TOC] 


Signed Scripts

For additional functionality, scripts can gain access to restricted information. This is achieved through signed scripts that request expanded privileges. The digital signature allows the user to confirm the validity of the certificate used to sign the script. It also allows the user to ensure that the script hasn't been tampered with since it was signed. The user then can decide whether to grant privileges based on the validated identity of the certificate owner and validated integrity of the script.

Note: This functionality provides greater security than tainting. Tainting has been disabled.

This section contains:

Recommended Reading

"Netscape Object Signing" provides a list of documents and resources that provide information on Object Signing, from creating the Java applet to getting a certificate to packaging and signing it

"Object-Signing Tools" provides information about the signing tools that allow you to create and manipulate JAR archives and digitally sign the files they contain. Tools include JAR Packager, JAR Packager Command Line Edition, and Page Signer.

Signed Script Requirements

You can sign JavaScript files, in-line scripts and event handler scripts. You cannot sign javascript: URLs or JavaScript entities .

Signed scripts require:

ARCHIVE attribute

All signed scripts (JavaScript file, in-line, event handler) require the <SCRIPT> tag's ARCHIVE attribute whose value is the name of the Java archive (JAR) file containing the digital signature. For example:

<SCRIPT ARCHIVE="myArchive.jar" SRC="myJavaScript.js">
</SCRIPT>

Event handler scripts do not directly specify the ARCHIVE; instead, the handler must be preceded by a script containing ARCHIVE. For example:

<SCRIPT ARCHIVE="myArchive.jar" ID="1">
...
</SCRIPT>
<FORM>
<INPUT TYPE="button" VALUE="OK" onClick="alert('A signed script')" ID="2">
</FORM>

Unless you are using more than one JAR file, you need only specify it once. Include the ARCHIVE tag in the first script on the HTML page and the remaining scripts on the page will use the same file. For example:

<SCRIPT ARCHIVE="myArchive.jar" ID="1">
document.write("This script is signed.");
</SCRIPT>
<SCRIPT ID="2">
document.write("This script is signed too.");
</SCRIPT>

ID Attribute

Signed in-line and event handler scripts require the ID attribute whose value is a string that relates the script to its signature in the JAR file. The ID must be unique within a JAR file.

When more than one event handler script exists in a tag, you only need one ID. The entire tag is signed as one piece.

In the following example, the first three scripts use the same JAR file. The third script accesses a JavaScript file so it doesn't use the ID tag. The fourth script uses a different JAR file, and its ID of "1" is unique to that file.

<HTML>
<SCRIPT ARCHIVE="firstArchive.jar" ID="1">
document.write("This is a signed script.");
</SCRIPT>
<BODY onLoad="alert('A signed script using firstArchive.jar')" 
      onLoad="alert('One ID needed for these event handler scripts')" ID="2">
<SCRIPT SRC="myJavaScript.js">
</SCRIPT>
<SCRIPT ARCHIVE="secondArchive.jar" ID="1">
document.write("This script uses the secondArchive.jar file.");
</SCRIPT>
</BODY>
</HTML>

Request Expanded Privileges

The script must include a function that calls Netscape's Java security classes and requests expanded privileges.

This requires one line of code that asks permission to access someTarget representing the resource you want to access. Targets are described below. For example:

netscape.security.PrivilegeManager.enablePrivilege("someTarget");

When the script calls this function, the signature is verified, and if the signature is valid, expanded privileges are granted. If necessary, a dialog displays with information about the application's author, and gives the user the option to grant or deny expanded privileges.

Java classes are explained in "Java Capabilities API."

Privileges are granted only in the scope of the requesting function and only after the request has been granted. This includes any functions called by the requesting function. When the script leaves that function, privileges no longer apply.

The example below demonstrates this by printing:

Function g requests expanded privileges, and only the commands and functions called after the request and within function g are granted privileges.

<SCRIPT ARCHIVE="ckHistory.jar" ID="1">
function printEnabled(i) { 
   if (history[0] == "") { 
      document.write(i + ": disabled<br>"); 
   } else { 
      document.write(i + ": enabled<br>"); 
   } 
}
function f() { 
   printEnabled(1); 
}
function g() { 
   printEnabled(2); 
   netscape.security.PrivilegeManager.enablePrivilege( "UniversalBrowserRead"); 
   printEnabled(3); 
   f(); 
   printEnabled(4); 
}
function h() { 
   printEnabled(5); 
   g(); 
   printEnabled(6); 
}
printEnabled(7); 
h(); 
printEnabled(8);
</SCRIPT>

Sign All Scripts

For any one script to request privileges, all scripts on the HTML page or layer must be signed. If you are using layers, you can have both signed and unsigned scripts as long as you keep them in separate layers.

You can sign JavaScript files (accessed with the <SCRIPT> SRC attribute), in-line scripts, and event handler scripts. You cannot sign javascript: URLs or JavaScript entities. If a javascript: URL, a JavaScript entity or an unsigned script is included on a page with signed scripts, the signed scripts act as if they had not been signed.

Re-sign Changed Scripts

Changed scripts must be re-signed.

Changes to a signed script's byte stream invalidate the script's signature. This includes moving the HTML page between platforms that have different representations of text. For example, moving an HTML page from a Windows server to a UNIX server changes the byte stream and invalidates the signature. (This doesn't affect viewing pages from multiple platforms.) To avoid this, you can move the page in binary mode. Note that doing so changes the appearance of the page in your text editor but not in the browser.

During development, you can request expanded privileges without signing the script by activating codebased principles as explained in Accessing Expanded Privileges Without Signed Scripts.

Creating Signed Scripts

  1. Include the ARCHIVE and ID attributes in the <SCRIPT> tag (ID for in-line and event handler scripts only).
  2. Include calls to Java classes requesting expanded privileges.
  3. Sign the script. For information see "Object-Signing Tools."

If a window with frames needs to capture events in pages loaded from different locations (servers), use enableExternalCapture in a signed script requesting UniversalBrowserWrite privileges. Use this method before calling the captureEvents method.

For a signed script to provide properties, functions, and objects to other signed or unsigned scripts, use the export statement. The script wishing to import these exported features needs to use the import statement.
 

International Characters in Signed Scripts

When used in scripts, international characters may appear in string constants and in comments (JavaScript keywords and variables cannot include special international characters). Scripts that include international characters cannot be signed because the process of transforming the characters to the local character set will invalidate the signature. To work around this limitation:

Note: There is no restriction on international characters the HTML surrounding the signed scripts.

Targets

The types of information you can access are called targets. These are listed below.

Target Description
UniversalBrowserRead allows reading of privileged data from the browser.
UniversalBrowserWrite allows modification of privileged data in a browser. 
UniversalFileRead allows a script to set the 'file' part of a file upload widget. This allows an arbitrary local file to be uploaded to wherever the form is submitted. 
UniversalPreferencesRead allows the script to read preferences using the navigator.preference() method. 
UniversalPreferencesWrite allows the script to set preferences using the navigator.preference() method. 
UniversalSendMail allows the program to send mail in the user's name.

For a complete list of targets, see "Introduction to the Capabilities Classes."

JavaScript Features Requiring Privileges

The following table lists the JavaScript features that require privileges and the target used to access the feature.

Feature Target
event object: setting any property  UniversalBrowserWrite
history object: 

Getting the value of any property 

Setting the preference property

 

UniversalBrowserRead 

UniversalBrowserWrite

DragDrop event: getting the value of the data property UniversalBrowserRead
navigator object: 

Getting the value of a preference using the preference method. 

Setting the value of a preference using the preference method.

 

UniversalPreferencesRead 

UniversalPreferencesWrite

window object: 

Adding or removing: 

  • directory bar 
  • location bar 
  • menu bar 
  • personal bar 
  • scroll bar 
  • status bar 
  • toolbar 

Using methods: 

  • enableExternalCapture -- when a window wants to capture events in pages loaded from different servers. Follow this method with captureEvents. 
  • close -- unconditional ability to close a browser window. 
  • moveBy -- to move a window off screen
  • moveTo -- to move a window off screen 
  • open -- when using 
    • innerWidth, innerHeight, outerWidth, and outerHeight to create a window smaller than 100 x 100 pixels or larger than the screen can accommodate
    • screenX and screenY to place a window off screen
    • titlebar to create a window without a titlebar
    • alwaysRaised, alwaysLowered, z-lock for any setting

  • resizeTo -- to resize a window smaller than 100 x 100 pixels or larger than the screen can accommodate 
  • resizeBy -- to resize a window smaller than 100 x 100 pixels or larger than the screen can accommodate 

Setting properties: 

  • innerWidth -- to set the inner width of a window to a size smaller than 100 x 100 or larger than the screen can accommodate
  • innerHeight -- to set the inner height of a window to a size smaller than 100 x 100 or larger than the screen can accommodate 
UniversalBrowserWrite
Setting a file upload widget UniversalFileRead
Submitting a form to mailto: or news: URL UniversalSendMail
Using an "about:" URL other than "about:blank"  UniversalBrowserRead

Example

The following script includes a button, that, when clicked, displays an alert dialog containing part of the URL history of the browser. To work properly, the script must be signed.

<SCRIPT ARCHIVE="myArchive.jar" ID="1">
function getHistory(i) {
   //Attempt to access privileged information
   return history[i];
}
function getImmediateHistory() {
   //Request privilege
   netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
   return getHistory(1);
}
</SCRIPT>
...
<INPUT TYPE="button" onClick="alert(getImmediateHistory());" ID="2">

Accessing Expanded Privileges Without Signed Scripts

Situations exist where you want to access privileged information without using signed scripts. Such a situation might be during development when you want to test your program, change code, retest, etc., and you don't want to sign the script after each change. You can request expanded privileges without signing the script by activating codebased principles. With codebase principals activated, Communicator allows the URL of the script to function as a principal for enabling privileges.

Risks

An unsigned script is vulnerable to tampering and should be used as a temporary measure or in the confines of an intranet.

Activating Codebased Principles

To activate codebased principles:

  1. Users of your program need to add the following line to their Netscape preferences file:
  2. user_pref("signed.applets.codebase_principal_support", true);

    File location varies from platform to platform. The following are likely locations:

    All instances of Communicator must be shut down before editing this file. After editing, start Communicator.

  3. Write the script with calls to the Java Class requesting expanded privileges. You can include an ARCHIVE and ID, but they aren't required until you sign the script.

When the user accesses the script, a dialog displays similar to the one displayed with signed scripts. The difference is that this dialog asks the user to grant privileges based on the URL and doesn't provide author verification. It advises the user that the script has not been digitally signed and may have been tampered with.

Note: If a page includes signed scripts and codebased scripts, and signed.applets.codebase_principal_support is enabled, all of the scripts on that page are treated as though they are unsigned and codebased principles apply.

Error Checking

To check for errors during development, open the Java Console which displays error messages. In the browser, choose Communicator > Java Console.


[Previous] [Next] [TOC] 



Copyright © 1997 Netscape Communications Corporation