Securing JavaScript

The Problem

Cross-site Scripting is a problem in the world of the internet. Someone hijacks your web site by injecting a little bit of JavaScript code and suddenly he/she has access to pretty much anything they want on your site.

Douglas Crockford gave a talk at the end of March last year (at least, that’s when his video was published on YUI Theater) that partially discussed this problem, and this article is largely based off that talk. He noted the web’s vulnerabilities to these types of attacks, mostly due to standards that must be implemented by the browsers and having very little to do with bugs. He also felt, though, that JavaScript is one the best languages for creating secure code.

Programming Concepts

Anyone who’s had any good training in object-oriented programming knows about the concept of Information Hiding. Information hiding is done to prevent access to information from anyone who doesn’t need to know what it is. A concept that fewer people have heard of is Capability Hiding. Capability hiding is preventing access to methods or actions from anyone who doesn’t need to do that action.

  • Information hiding: Need to know
  • Capability hiding: Need to do

There should only be 3 ways to obtain a reference to an object. If your application is implemented in way that prevents access except via these three ways, your application may be secure. However, if there are other means to obtain access, your application is not secure. Here are the 3 ways:

  1. Creation: If you created the object, then you should have access to it.
  2. Construction: If your constructor created the object, you should have access to it.
  3. Introduction: If someone gave you the object, you should have access to it.

Let’s use some diagrams straight from Crockford’s speech to demonstrate how you can hide and grant access to actions via introduction. To start out, Image 1 below shows three objects: A, B, and C.

A with access to B and CA with access to B and C

You can assume that A probably got access to B and C via either creation or construction. B and C, however, have no reference to A, nor do they have references to each other, so they have no way to communicate without those referenced.

In Image 2 below, A is calling B, and passing C in as an argument. In this way, A is introducing B to C.

A calls B, passing in CA calls B, passing in C

For those of you who may be having a slightly difficult time mapping diagrams to code in your head, the simplest way to represent this code is shown in Script 1 below. It’s extremely simple.

1
2
// Script 1: This call is made within A
B(C);

Now that B has been given a reference to C, it has the capability to communicate with C any time that it wants to, as show in Image 3.

B can communicate with CB can communicate with C

C still has no access to B or A, nor does B have access to A. However, A has the ability to grant access to B and itself and B has the ability to grant access to itself.

Another problem arises, though, when you only want B to be able to access C one time. In his speech, Crockford shows off some powerful code that allows A to revoke B’s access to C at any point.

The Global Problem

This model gives you the ability to create a secure system… almost. There’s one problem left: the global object. If you declare anything outside of a function, it’ll be attached to the global window object. This allows it to be accessed by anyone because everyone has access to the global object.

There is one pattern that can help with this, though. It’s called the immediately invoked function expression. It’s looks a little bit like this:

1
2
3
4
5
// Script 2: Immediately Invoked Function Expression (IIFE)
(function() { // The function has no name and is not assigned to a var
// Everything in here is hidden from the global
// scope due to JavaScript's "function scope"
}()); // Because I have the () right away after the }, it runs immediately

As it says in the code comments, it executes right away, just like all of your other code outside of functions, so it’s just like normal code, except it’s all inside of a function so that every variable declared within it is private to that function. I’m sure you can do a search for “anonymous self-invoking function” and you’ll find more information.

Coming to a Close

You can go to Douglas Crockford’s video to see him give the presentation himself and to get some more insight into the world of JavaScript. The video was part 5 of his “Crockford on JavaScript“ series.

He also recommended a couple other resources within the video:

I hope this gets you thinking about security of your JavaScript applications. If you thought this was helpful or you just plain liked the article, please spread the word using the social sharing buttons below the post. Thanks!

Author: Joe Zimmerman

Author: Joe Zimmerman Joe Zimmerman has been doing web development ever since he found an HTML book on his dad's shelf when he was 12. Since then, JavaScript has grown in popularity and he has become passionate about it. He also loves to teach others though his blog and other popular blogs. When he's not writing code, he's spending time with his wife and children and leading them in God's Word.