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:
"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.
You can sign JavaScript files, in-line scripts and event handler scripts. You cannot sign javascript: URLs or JavaScript entities .
Signed scripts require:
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>
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>
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:
7: disabled
5: disabled
2: disabled
3: enabled
1: enabled
4: enabled
6: disabled
8: disabled
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>
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.
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.
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.
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.
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."
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:
Using methods:
Setting properties:
|
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 |
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">
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.
An unsigned script is vulnerable to tampering and should be used as a temporary measure or in the confines of an intranet.
To activate codebased principles:
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.
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.
To check for errors during development, open the Java Console which displays error messages. In the browser, choose Communicator > Java Console.