Although JavaScript has had its share of security concerns, many of those issues were addressed and resolved early on. In fact, JavaScript security has steadily progressed, with items such as excluding support for certain capabilities, restricted features, the “same origin” policy, security zones, and signed scripts. The main exception to this progress was Netscape Navigator’s past experiment with the data tainting security model. Let’s take a look at how these features contribute to JavaScript’s security improvements.
Browsers have different security holes
JavaScript security isn’t really troubled by its cross-browser and cross-platform nature. With some modifications, a script that runs on Internet Explorer on a Mac will also run on Netscape on a PC. However, the original diversity of platforms and browsers, which were once a real pain to develop for, also means that the individual browsers don’t usually have the same security holes. So the odds are that while a malicious script may cause problems on Netscape, it will fail on Internet Explorer, Opera, and Mozilla.
Today, because of the prevalence of a single browser, it’s a little like having every farmer in a country raising the same variety of the same crop. A single disease could conceivably wipe out the entire harvest for that year and plunge that country into famine. That’s a somewhat simplified view, but consider that a script that executes on my wife’s Dell with Windows XP will run on her mother’s XP with Windows 98 and on my Toshiba with Windows 2000 Server. Fortunately, although it may seem to the casual observer that JavaScript is completely lacking in security features, that isn’t the case; JavaScript does in fact have a limited number of security features.
The data tainting security model
Netscape Navigator 3 introduced the short-lived concept of data tainting. When enabled, data tainting allowed one browser window to see the properties of another window regardless of what server the window was loaded from. The author of the second page needed to mark which properties where tainted and therefore could not be passed on to a server. Although it was an interesting idea, it required defensive coding, and the client had to enable data tainting.
You can’t get there from here
One important part of client-side JavaScript’s security is that there are a number of things you just can’t do. There are no objects with which to access the client’s files, interrogate the client’s network connections, execute operation system commands, or execute programs. At times, this lack of certain features can be annoying, but it prevents a world of problems.
Restricted features
Anyone who has recently tried to execute a self.close() on the parent browser window knows that JavaScript will in fact try to stop some malicious code. When the Web was young and JavaScript was new, some individuals amused themselves by closing a visitor’s browser windows. After a few months of that, self.close() on the parent browser window became a restricted feature.
There are, in fact, a number of restricted features covering the spectrum of JavaScript features. They include accessing the browser’s history collection, uploading files, submitting, mailing, altering menu bars, and opening windows that are less than 100 pixels on a side, which could go unnoticed by the user.
Same origin policy
A script is permitted to read and alter the properties only of documents that have the same origin. This same origin policy also covers both the port and the protocol. So if a script’s origin port is 80 and the protocol is HTTP, switching to port 21 and FTP is not permitted. The logic behind this restriction is to prevent theft of information. Let’s say that I’m a bad guy. If the origin restriction didn’t exist, as long as my script was running, I could take any information entered in another browser window and send it to my Web site using XMLHTTP or another method. Of course, most of the information would be useless, but occasionally I would strike gold and get a credit card number. Talk about your data mining!
The origin security restriction applies not only to documents but also to the browser’s cookie collection. This prevents the bad guy from copying cookies that identify an online shopper to the shopper’s own browser and thus become, in the eyes of the shopping site, that shopper.
Enabling a nice shopping spree–with no pesky bills
With most policies, there are exceptions, and that’s true of the same origin policy. The policy doesn’t apply to a script with the UniversalBrowserRead privilege. Scripts with this privilege are allowed to read properties of documents with a different origin. The UniversalBrowserWrite privilege permits scripts to write properties. The ability to read and write properties with a different origin can be obtained through the use of both privileges or through the use of the UniversalBrowserAccess privilege.
Zones and signed scripts
Microsoft Internet Explorer and Netscape Navigator each have their own method of handling security. Internet Explorer handles it through the use of zones. With Internet Explorer version 5.5 these zones are Internet and Local Intranet, along with Trusted Sites and Restricted Sites. These four classifications allow the user or an administrator to set, with a degree of granularity, what JavaScript can and cannot do by the zone. Somewhat finer control is available by specifying security on a site-by-site basis. It is important to remember that Internet Explorer doesn’t use security to relax restrictions; it uses it to further restrict capabilities.
Netscape Navigator, on the other hand, administers security using a digitally signed script. This gives individual scripts the ability, pending user approval, to relax restrictions to various JavaScript features on a feature-by-feature basis. Although signed scripts are an interesting approach to security, they do not guarantee that the script isn’t malicious. A signed script merely establishes identity, and even then it isn’t a guarantee of identity.
One JavaScript security feature is common to all browsers. On the browser, JavaScript, like Java, runs in a “sandbox.” In essence, when on the browser, JavaScript has restricted capabilities on the client. Regardless of what people say, without user intervention, JavaScript cannot reformat your hard drive, change the contents of files, or make your cat go bald. To accomplish anything outside the sandbox, it is necessary to go beyond the browser.
No more growing pains
The majority of JavaScript security issues occurred in the past, when browsers, JavaScript, and the Web were all new and experiencing growing pains. As JavaScript and browsers mature, the security risks have begun to diminish.