JavaScript Security

In your evolution as a web developer, you’ll run into some security problems eventually. The makers of JavaScript have identified and solved most of the really glaring security holes; the browser vendors have plugged up some the holes themselves, along with adding a certain measure of guaranteed security through browser operations. There are several different approaches to security inherent in JavaScript. Each has its own pros and cons, but as a whole they work pretty well. Some of the security procedures are within the JavaScript interpreter, and some are within the browser itself. As you begin to develop, you (or your employer) will no doubt insist on the implementation of some measure of security. Not taking security considerations into account will lead to tampering. It’s a fact, so you have to deal with it. Leaving out security in your development will open your creation (and your company) to tampering. Your site users will not use your offered content when word gets out that they are vulnerable due to your security holes.

The browser runs off of the operating system itself; this means that the file system of the user’s machine is a potential target for malicious users. It is entirely possible to access a user’s directory listing through JavaScript. Hackers know this, and exploit it on a regular basis. Security starts with your servers, because it is there that the user downloads—and executes upon their machine—your code. Your servers must be tightly controlled and regularly monitored. Your code must be clean, leaving no threads open to outside access. This is the developer’s responsibility.

User responsibilities are basically whether or not to trust your content to run in their machines, leading me back to the security you, the developer, will implement. This ability to trust your content and run or not run your scripts is within the capabilities of the browser; it is a setting in the preferences section of the browser.

The Problem with Frames

When the first instances of frames were implemented on the Internet, it took all of two months for the first major security holes to open up and be recognized by the hacking community. To understand how frames were used to present a security hole is to first understand frames themselves.

The way a web page renders frames is as follows:

  1. A page with instructions for the frames to be rendered is loaded.
  2. The addresses and particulars of how the frames will be rendered such as border properties and the placement of the frames themselves is given to the browser.
  3. The documents that will be used to display the content of the frames are then loaded into the given frames.
  4. The page is then rendered (displayed) to the browser window.

Within this procedure is the ability to load and execute web pages from other servers on other domains. The JavaScript variables from one domain are available for examination and modification to the web pages from the other domains that are used within the other frames that make up the page. The first strategy to combat this problem was the Same Origin Policy, which was taken up by Netscape Navigator, Internet Explorer, and Opera.

The Same Origin Policy: Security the Internet Explorer Way

The Same Origin Policy prevents JavaScript code that was sent from one server to access the properties of a document sent from another server, another port, or another protocol and return that information to the original server. The Same Origin Policy does not affect all elements of an HTML document, but rather the key JavaScript elements that a functioning script within an HTML document cannot be executed without. The elements that are enforced by the Same Origin Policy that must pass an origin inspection are as follows:

  • document: The reading and writing of the anchors, applets, cookies, domains, elements, embeds, forms, lastModified, length, referrer, title, and URL methods and properties. Also verified is each instance of a form element, and all Java CLASSes available to a JavaScript function via LiveConnect.
  • image: The lowsrc and src properties.
  • layer: The src property.
  • location: Every property available to location except location.x and location.y.
  • window: The find property.

You can see that most of the functionality of the common JavaScript script must use at least one of the properties and methods that must pass the origin inspection, making it next to impossible to maliciously alter or access the scripted functions of a framed window.

Occasionally, you may have a need to go against the Same Origin Policy to achieve the desired result from your web application. An exception has been made to address this possibility. To access the information within a page created and displayed within one of the page frames, you would use the “document.domain” statement to list a domain that is trusted by the web application and thus the browser. For example, for a page that originated at http://developer.walkthegeek.com to access variables and scripted entities from a page that originated at http://www.walkthegeek.com, you would use the following statement within your function:

document.domain = "walkthegeek.com";

Setting the document.domain property in this way tells the browser to trust all content from the domain www.walkthegeek.com as well as all subdomains of walkthegeek.com, such as the aforementioned developer.walkthegeek.com.

Data Tainting: Security the Netscape Way

When it was seen that more security was needed to protect Internet users, Netscape initiated a new type of security that was more powerful than anything previous: Data Tainting. Data Tainting is a combination of the Same Origin Policy and a setting on the client (user’s) computer. It works in much the same way. It controls the right to trust another domain and access JavaScript variables and objects from a page served from a different server, and can be turned on and off at will. Basically, if Data Tainting is turned off, a message window will pop up saying that accessing JavaScript entities on pages from another domain is not allowed.

Because the Data Tainting is part of your operating system, it cannot be turned on and off through the browser. Examine the following list that states how to enable Data Tainting in the various operating systems. It’s really quite easy to do.

  • Windows – NS_ENABLE_TAINT=1: Place the statement given in the autoexec.bat file for Windows 3.1X, 95, 98, and NT. For Windows NT, you also may set data tainting as a User Environment variable.
  • UNIX – NS_ENABLE_TAINT=1: This one depends on which UNIX shell you are operating with. Basically, you would set an environment variable through the use of the set env or env commands.
  • Macintosh: You would remove the two forward slashes before the NS_ENABLE_TAINT statement, which can be found by editing the resource of type envi and number 128 in the Navigator application itself. The NS_ENABLE_TAINT statement should be near the end of the document.
  • OS/2 – NS_ENABLE_TAINT=1: Set the given statement in the config.sys file in the root of your startup drive.

Applying Data Tainting only affects Netscape’s Navigator. Because Data Tainting works in much the same way as the Same Origin Policy, not all page elements are tested for their origin, only the absolutely essential parts a JavaScript script cannot exist without are tested. The list is as follows:

  • document: The cookie, domain, lastModified, links, referrer, title, and URL properties
  • form: Every instance of a form element
  • history: The current, next, previous, and toString methods and properties
  • link: The hash, host, hostname, href, pathname, port, protocol, search, and toString properties and methods
  • location: The hash, host, hostname, href, pathname, port, protocol, search, and toString properties and methods
  • option: The defaultSelected, selected, text, and value properties and methods
  • plugin: The name property
  • window: The defaultStatus, name, and status properties and methods

All of the above are tested for its origin. You may test to see whether Data Tainting has been enabled through the use of the taintEnabled() method, which will return a value of true if it is enabled or false if it isn’t. You also may specify elements of your script that are to be tainted. It should be noted that Data Tainting is available only to JavaScript versions 1.1 and lower. The versions of JavaScript starting with JavaScript 1.2 use a different type of security: Signed Scripts.

Signed Scripts

Signed Scripts are used to gain access to certain restricted information about the client’s (the user’s) computer. It uses LiveConnect and the Java Capabilities API (Application Programming Interface) to access this restricted information. With this model, you have the ability to “sign” external JavaScript files with your Security Certificate. Your Security Certificate is like a fingerprint—it is unique to you or your organization. Security Certificates can be created through the use of Netscape’s Page Signer Tool, which is available online, free of charge, at http://developer.netscape.com. Select the Tools option on the Site Map.

Netscape’s Page Signer tool will allow you to create your individual and unique online security identification. The tool builds a JAR (Java Archive) file that includes both your security certificate and your code. When the document has an HTML SCRIPT tag that has the ARCHIVE attribute set, the browser performs a verification check before the code is executed. An alert box pops up and gives the user a chance to accept or decline the running of your script. If the script is included within the document and not within an external .js file, the JAR file should include only your security identification, although it is still accessed through the use of the ARCHIVE attribute.

Because the user can accept or decline a script from running, Netscape has provided another level to the security that can be enforced by the user. Some think it to be too user-driven to use often. By this I mean that the browser will ask too many questions for what areas of the script to be run, causing increased user annoyance. The areas of the script that are available to be accepted or declined through the use of an alert box are set using the Java method “netscape.security.PrivelidgeManager.enablePrivelidge()”. Here is a list of options that a developer can attempt to have the user verify:

  • UniversalBrowserAccess: This method allows both the reading and the writing of priviledged data in and to the browser.
  • UniversalBrowserRead: This method allows only the reading of privileged data in the browser, and is required when using the history object or getting the value of a DragDrop value within the browser.
  • UniversalBrowserWrite: This method allows only the writing of privileged data in the browser, and is required when using any property of an event object, adding or removing any of the browser’s content bars (status bar, menu bar, and so forth), and setting the window object’s values within the script.
  • UniversalFileRead: This method allows the reading of the file system of the user’s machine, and is required when using the fileUpload() method.
  • UniversalPreferencesRead: This method allows the script to read and report the browser’s preferences settings.
  • UniversalPreferencesWrite: This method allows the script to set the preference settings within your (the user’s) browser.
  • UniversalSendMail: This method allows the script to send an email with the user’s name, and is required when using the news: or mailto: attributes within a script.

You can see that the aforementioned pros and cons are quite evident here. Additionally, each of the two major browsers—Microsoft’s Internet Explorer and Netscape’s Navigator—have differing security measures in place. Internet Explorer uses the Same Origin Policy, whereas Netscape uses the Signed Scripts method. Each is good, in its own way. What is frustrating, as you’ll see when you attempt to enforce security, is that they are very different. A totally different directory path for each is sometimes required, effectively doubling the work you’ll have to put in to satisfy the security considerations for each browser.

Conclusion

Hopefully, this article has helped you understand the security problems that your users may encounter and how you can prevent problems with your JavaScript coding. When coding, look out for the potential security issues discussed here. Remember that you can use the same origin policy, data tainting, and signed scripts to tighten those security gaps.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read