Instead of preventing scripts from reading private data, a better approach would be to prevent them from exporting it, since this is what we are trying to prevent in the first place. If we could do this, then we could lift most of the hobbles that were detailed in the sections above. (We'd still need some hobbles, to prevent a program from closing windows it didn't open, for example.) Unfortunately, preventing the export of private data can be tricky to do, because not only must we prevent a script from exporting private data directly, be we must also prevent it from exporting data derived, in any way, from private data. If you think through the implications, you can see that keeping track of the data that must not be exported could be a very difficult proposition.
As we can see, tainting does not prevent all tainted data from being exported; it merely prevents it from being exported to a server that does not already "own" it. Furthermore, tainting does not even absolutely prevent data from being sent where it shouldn't be; it only prevents it from automatically being sent there. Whenever an attempt to export data violates the tainting rules, the user will be prompted with a dialog box asking them whether the export should be allowed. If they so choose, they can allow the export.
// b is a tainted Boolean value that we want to export if (b == true) newb = true; else newb = false; // Now newb has the same value as b, but is not tainted, so we could // export it if this script itself did not become tainted in the process.
In addition to understanding the different types of taint that are possible, you should also understand just what is meant by "exporting" data. In general terms, this means sending data over the Net. In practical terms, it occurs when a form is submitted in any way, or when a new URL is requested in any way. It is obvious that form submission exports data, but is less obvious that requesting a new document exports data. Bear in mind though that arbitrary data can be encoded into a URL following a question mark or hash sign (#). Also, the file and path of a URL can encode information.
As noted above, the data-tainting security model is experimental in Navigator 3.0, and is not enabled by default. It is expected to be the default security model in version 4.0 of Navigator, however. If you want to try using data tainting with Navigator 3.0, you must enable it by setting an environment variable before starting Navigator. On Unix systems, do this with the following command in csh:
setenv NS_ENABLE_TAINT 1
Note that if you enable this security model, you may find that many more scripts than you expect produce taint violations, and you'll spend a lot of time responding to dialogs that ask you to confirm form submissions or new page requests. One of the main reasons that tainting was not enabled in Navigator 3.0 was that the user interface to support it well was not yet ready. Thus, for Navigator 4.0, we can hope to see a smoother UI that does not ask as many questions.
Table 20.1 lists the object properties and methods that are tainted by default. The taint() and untaint() functions that will be introduced below allow you to modify these defaults.
Table 20.1 shows the object properties and methods that are tainted by default in Navigator 3.0. This list is not the final word on tainting. If a script would like to prevent other data it owns from being exported, it may taint that data with the taint() method. Similarly, if a script would like to relax the data-tainting rules in order to allow information it owns to be exported more freely, it can remove its taint from a value with the untaint() method.
The second point to note is that a script can use untaint() only to remove its own taint from a value. If a value X carries taint that identifies it as owned by server A, then a script running in a document from server B may call untaint() on value X but will not succeed in removing server A's taint, and will not be able to export that value to server B.
Finally, if taint() and untaint() are called with no argument, then they add and remove taint from the script rather than from a particular object. Again, a script can only remove its own taint from itself: if a script from server A has tainted itself by examining tainted data owned by server B, then server A cannot remove that taint from itself.