captain holly java blog

Javascript silo proposals

Posted in Uncategorized by mcgyver5 on March 26, 2010

This post was inspired by a recent Security Now podcast (transcript) that featured John Graham-Cumming and reviews ways to secure Javascript by doing things like separating namespaces and working with subsets of Javascript.

Javascript code commonly lives all together in the same namespace. That is, if you visit a page with included Javascript code from several sources, the code from one can, by default, call code and change code from the others.

Not only can other scripts access fields and functions of Javascript objects, alter their values, but they can replace functions themselves with functions of their own.
This is true most of the time and it is a huge security problem.
A common perception from the web is that this doesn’t matter, that security “is a server-side concern”, that fears are overblown, that any restrictions on Javascript will screw up the web 2.0 “revolution”. Whoa.
Consider what a third party script on your page can do:

  1. pull in additional scripts from anywhere
  2. make requests to to the server
  3. Request information from the user
  4. Get around same origin policy and share information with anywhere

Think of the ad-based attacks against the New York Times a year ago and then the attacks against Yahoo, Fox News and Google from the other day. These are examples of the well known sites. Think of all the second and third tier sites that will place active content on their pages for a fee. Attackers can just purchase ads!

Closures
Javascript does have a way for a programmer to silo their script. This is called a closure. Closures require some “leveling up” in Javascript skill and this entire article is a must-read. I could not really grasp “closures” until I read an article about closures that did not use the word “closure”. A closure is a function specially defined inside another function. These “inner functions” can be treated like private java methods.
Simple Javascript Closure Example:
normal Javascript without closures (all functions are “public”)

function getUsername(){
 return username;
}

as part of an object:

var f = function(){
  var username = "tim"
function getUsername(){
   return username;
}
}

any code on the page can call f.getUsername(); and get the username

but when using closures

f = function(){
   
    // this function is made private
   function getCookie_private(){
        alert(document.cookie);
   }
   return {

         // a public variable:
         var screenName = "Sue-ellen";
        // a public function
         function publicStuff{
              alert("hello everyone!");
         }
}();

that syntax looks weird because of the parenthesis at the end. These are important because it makes this entire function run immediately, constructing itself and then
returning the block after the “return” keyword as THE function. Except this function now has some private parts accessible only by itself!

using this idea, you can create namespaces with these anonymous functions:

com.wordpress.captainholly = function(){

///  all kinds of public and private functions and fields
....
}();


This is explained here.

Closures make it so an “inner function always has access to the vars and parameters of its outer function, even after the outer function has returned.” This makes it possible for com.wordpress.captainholly private methods to keep their knowledge of the object they are part of so that
com.wordpress.captainholly.currentUser.screenName is not a fake idea.

This article carries this idea further to create “Durable” objects — objects that, even though they have publicly accessible methods cannot have them switched out by another script.

Web security cannot rely on every Javascript programmer both understanding and consistently using closures. We need something more. Some products have come out that attempt to silo and otherwise secure Javascript on the fly.

A Google project called Caja is a safe subset of JavaScript. It drastically rewrites code and supposedly isolates functions properly so that other scripts can’t call them. They have a nice testbed that shows the rewritten code and the browser behavior that results.

ADsafe is a technology promoted by Douglas Crockford himself. AdSafe encapsulates included code, forcing it to interact with ADSafe as a proxy object between it and the rest of the page. External code is only allowed access to the ADsafe Object. The ADsafe object then addresses the rest of the page, the DOM etc. in a safe manner.
A sampling of what Adsafe brings, enhanced by Douglas Crockford’s Powerpoint presentation:

  • No access to the “document” object
  • take away most of the access to DOM objects through subscripts. With adsafe, you have to use ADSAFE.get() and ADSAFE.set() instead of someControl[‘importantControl’]
  • No using the “this” keyword
  • some of the other keywords not allowed: apply, arguments, call, callee, caller, eval, prototype, valueOf
  • Dom interface is query based and scope of queries is limited to the content of the div of the third party widget
  • Guest code has no access to any DOM node.
  • Only the “guest” code has to operate through Adsafe. The home site’s code can still do anything.

Another proposal for buttoning down Javascript is Mozilla’s Content Security Policy, CSP, which proposes to restrict the way JavaScript is used in the browser.
The CSP specs have a long list of features that give granular control over such things as :

  1. A general “allow” directive that lets the website owner define which remote sites can provide resources.
  2. An ancestor-pages directive that allows the website owner to restrict other sites from framing the site. Used properly, this cancels out a big vector for cross site scripting attacks.
  3. More granular directives that allow the site owner to define which domains may provide object, css, image, and Javascript elements to the page in question.
  4. Where to report unauthorized access attempts

Settings are controlled through a header. Using a response.setHeader() in java, here are a few examples:
To allow only resources originating from same domain:

response.setHeader("x-content-security-policy", "allow 'self'");

To allow no other site to act as a frame for the page being loaded:

response.setHeader("x-content-security-policy", "frame-ancestors self");

The CSP can be toggled off and on through the about:config interface. It won’t affect pages that don’t have a CSP header and pages that have CSP headers can still run in browsers that don’t implement CSP. Of course, since clients can’t be sure that the web site will enforce CSP and the web site can’t be sure that the browser will implement it, this just amounts to an interesting proto-standard that might help us understand where the web will have to move some day.

Users can protect themselves
While waiting for browsers and servers to implement these protections, individual users can protect themselves by using the NoScript Firefox extension. First of all, Noscript prohibits Javascript from sites you haven’t approved from running at all. On top of that, Noscript includes a module of ABE (Application Boundary Enforcer) that does something very similar to Mozilla’s CSP. When you first visit a website and decide to allow Noscript to allow scripting on this website, ABE takes over and enforces firewall rules about what outside resources, if any, may interact with the current site.

This post is just about ways to secure Javascript, which is just a part of overall browser security. For a complete treatment of browser security, see the excellent and constantly evolving Google browser security handbook.

Advertisements

2 Responses

Subscribe to comments with RSS.

  1. The Java Code said, on August 17, 2010 at 9:02 am

    thank you for this very important article about javascript
    I did not know about the code closure before this

  2. Sebastian said, on September 16, 2011 at 1:36 pm

    Very nice stuff.

    Thanks for sharing.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: