Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

4.18.2011

ESAPI4JS - Very good write-up by Marcus Niemietz

So late last week, I recieved the final copy of a paper written by Marcus Niemietz that takes a deep dive into the ESAPI4JS Proof of Concept I wrote over a year ago. I was quite surprised, to say the least - and a bit humbled by 20+ pages of text on the project.

It's funny, I was just thinking about digging in my heals this spring and running through this code again - clean it up, trim a bunch of fat - and possibly do some additional integration into further jQuery plugins. Seems that I am not the only one who has been thinking about this project lately and that is great news!

First and foremost - I have reposted the entire report (with the author's permission and OWASP's) over on the OWASP Site.

Marcus spends some time discussing the project and concept of the project as well as the ESAPI project as a whole first off. Ths lays the groundwork for his paper and is probably stuff that most of you (my readers) already know. He also corrects some mistakes in the installation guide (that will be reflected on the wiki as soon as time allows). In addition he also spends some time discussing the assessment criteria and specifically how they relate to this project.

Once we get passed all of that, we get into the real meat of the paper.

Section 3 focuses on improvements that could be made to the project and this is where I would like to spend most of my time in this post.

3.1.x - Retrofitting Security

Marcus calls out a point here that a mature SDL will have isolated the "risks" of the application prior to any development being done. This is generally very true for shops that have an established and mature SDL - but that statement definitely does not apply to the majority of software development shops that are writing applications for the web today. The idea of retrofitting security into an existing application is paramount to the idea behind ESAPI. It is imperative that developers have the ability to integrate ESAPI controls into existing applications because there are a lot more insecure existing applications on the internet right now then there are new applications being built. Several large shops have legacy applications that are no longer actively maintained unless there is a problem, some have such massive application portfolios that it isn't realistic to expect rewrites and large redesigns, and the majority of the applications that are live (and vulnerable) on the web today are smaller "Mom and Pop" applications. This is the target market for ESAPI!

3.2.x - Modification of Objects


I heartily agree this is a huge issue - and one that I have passionately spoken out about whenever the opportunity arises. The fact of the matter is that until Javascript accepts the fact that some objects just *need* to be immutable, security will always be just another stepping stone for the attacker to (easily) overcome in the browser. In specific Marcus refers to the ability to overwrite objects in the DOM by referencing HTML Elements with the same id in Internet Explorer. While this is indeed a problem, the issue is much larger and depends 100% on the forced implementation of Immutable Objects in ALL browsers as described in the ECMAScript 5 Specification

3.3.x - Redundancy


This is a tricky issue in some regards, while most of this is due to the fact that I was simply creating a proof of concept that this could be done in Javascript - I also am a firm believer that all implementations of the ESAPI (regardless of language) should follow a well defined API specification. Because of this, it is to be expected that there will be some redundancy in some languages - some methods that perhaps just don't make sense in the language (such as the illustrated escape/unescape methods) will be implemented anyhow just to enforce the contract (implied in JS of course) of the API.

Adding more Validation!


I  agree with this to a certain extent - I think that all the suggested validators should be "available", but there is no need for my user registration form on my small used book store to require validation of International Bank Account Numbers - it does however make sense to provide ISBN validation. This problem (I believe anyhow) is addressed very well in the jQuery Plugin architecture and I would ultimately like to see this same type of architecture implemented into future ESAPI4JS implementations.

Summary


All in all, I think Marcus did a great job researching and presenting his case in this paper, and I highly recommend that everyone give it a read and comment. I look forward to reading your comments and rebuttals  - this is how we change the world people. One small debate at a time. :)

3.07.2011

New Encoding - Property Aware Contextual Encoding

After some conversations over Twitter with the the XSS Ninja known as Gareth Heyes regarding different escaping needs that went even further than just having the context itself. Basically, the gist of the conversation asserted that different escaping rules applied to different CSS properties, for instance the background-color property accepts Hexadecimal color codes (#CCCCCC) or rgb color (rgb(100,100,100)) formulas as well as plain-text well-known color keywords (blue) - this is drastically different than what would go into something like say the width property - which would simply be a fixed size or percentage. It was at this point that we came to the conclusion that jquery-encoder should use the property name that is being encoded for to determine the correct escaping syntax.

The new API for the property aware encodeForXXX methods follows

  • encodeForCss(property,data,omitPropertyName)
    Returns the encoded property: value pair, escaped in the context of the passed in property. Banned properties are the behavior family (behavior,-moz-behavior,-ms-behavior) as they are not safe to be set using untrusted data and allow for script injection by definition. Values that contain the expression keyword will also be rejected as unsafe, as this is the equivelent of calling the javascript eval within a style context. If the optional omitPropertyName is true the function will return only the value encoded for the passed in property.
  • encodeForHTMLAttribute(attribute,data,omitAttributeName)
    Returns the encoded attribute="value" pair, escaped in the context of the passed in attribute. Banned attributes are href and src as those should be encoded using the encodeForUrl function. The javascript event hooks on* are also banned as they should be set using the encodeForJavascript function. The style attribute should be set using the encodeForCSS function. If the optional omitAttributeName parameter is true, the function will return only the value encoded for the passed in attribute.

In all cases, the property/attribute names are canonicalized prior to encoding to validate and get the escaping context for that property (or the default if there is no specific context specified)

This was a somewhat difficult decision to make, simply because it is mixing in a bit of validation with the output encoding control - which is not necessarily ideal from a pure design standpoint. I felt however, that this was a necessary evil in order to ensure correct encoding/escaping context and get the most value from the plugin.

Please continue to send me your thoughts and ideas for the plugin - I plan on releasing it to the general public through the jQuery plugin repository within the next couple weeks so any feedback from the community leading up to the release of the plugin will only make it stronger!

As always, the latest version of the plugin is available from my github
https://github.com/chrisisbeef/jquery-encoder

The sandbox (which will be updated with the latest version today) is available on my site:
http://software.digital-ritual.net/jqencoder/

2.21.2011

jQuery-Encoder updated

I have made several updates to the jqencoder plugin over the weekend and thought I would share a little about them quickly.

Plugin Readme: http://bit.ly/ie4J04

First, and most importantly - I have added a series of static methods (that look similar to the methods on the Encoder interface for ESAPI) to perform particular contextual encoding tasks - specifically when building html dynamically rather than building elements up using the DOM.

  • encodeForHTML
  • encodeForHTMLAttribute
  • encodeForCSS
  • encodeForURL
  • encodeForJavascript

Each of these methods can be accessed under the static $.encoder context.

$.post('http://untrusted.com/external_profile', function(profile) {
      $('#widget').html('<div id="untrusted_widget" width="' + 
                        $.encoder.encodeForHTMLAttribute(profile.width) + 
                        '" onmouseover="' + profile.callback + "(\'' +
                        $.encoder.encodeForJavascript(profile.parm) + 
                        '\')">' + $.encoder.encodeForHTML(profile.data) + 
                        '</div>');
   }

In addition, the $.canonicalize method has also been moved into the $.encoder context.

$('#phonenumber').blur(function() {
      validatePhoneNumber($.encoder.canonicalize(this.val());
   });

The third, and final big change over the weekend - was solidifying the ES5 immutable objects protection. If it is supported by the browser, the $.encoder object will be frozen, sealed, or non-extensible (in that order of priority) to protect the encoding and canonicalize functions themselves from being tampered with at runtime. At this point in time, Chrome has implemented Object.freeze in the latest release version, Mozilla has implemented it in Firefox 4 and Microsoft have implemented it in IE9. Safari shows no indication of implementing it, and neither does Opera.

Now, I pose a question to the developers that may use this plugin. Is there a need to keep the instance method $.fn.encode? It seems to me that due to the nature of setting DOM element properties via Javascript, that this is not really needed at all. So, should I nuke it?

I end this post with a final thought (continuing from my above conversation of Object.freeze)

I strongly recommend that developers start taking the initiative to make their custom JS objects immutable, and also recommend making framework objects immutable as well. If you were to (using jQuery) issue the following in your onready handler

$(document).ready(function(){
   if ( Object.freeze ) $ = Object.freeze($);
   // .. initialize page below here
});

It seems to me, this could eliminate a lot of potential vulnerability exploitation of bugs in framework code. What are your thoughts?

Also, why not consider the following:

var lock_objs = [ String.prototype, 
                     Array.prototype, 
                     Function.prototype, 
                     Object.prototype ];
   for (var i=0;i<lock_objs.length;i++) lock_objs[i] = Object.freeze(lock_objs[i]);

1.24.2010

ESAPI4JS - v0.1.3 Now Available

The newest installment of the ESAPI4JS is now available! In light of that, I decided it may be helpful to throw out some examples of how this framework can be used to help protect clients from browser based attacks like DOM Based XSS, and how the API could help to provide some additional client side security.

First let's take a look at the biggest benefit to using ESAPI4JS - The ability to mitigate client-side DOM Based XSS attacks. This is something that no other framework that I am aware of is yet to tackle, and as such, I think that we will begin to see this vector being exploited more and more in the wild.

Let us start at the beginning.

What is DOM Based XSS?

Who better to answer that question, than the experts at OWASP?

DOM Based XSS (or as it is called in some texts, “type-0 XSS”) is an XSS attack wherein the attack payload is executed as a result of modifying the DOM “environment” in the victim’s browser used by the original client side script, so that the client side code runs in an “unexpected” manner. That is, the page itself (the HTTP response that is) does not change, but the client side code contained in the page executes differently due to the malicious modifications that have occurred in the DOM environment. - OWASP

The most common type of vulnerable code that this affects is code which uses the information that is in the window.location global object.

Let's work through an example of the vulnerable code, and how it could be mitigated using ESAPI4JS.

<html>
<head>
   <title>My Vulnerable Webpage</title>
   <script type="text/javascript">
      var getParameter = function( name ) {
         var startIdx = window.location.href.indexOf( name ) + name.length + 1;
         var endIdx = window.location.href.indexOf( '&', startIdx );
         if ( endIdx = -1 ) endIdx = window.location.href.length;
         return window.location.href.substring( startIdx, endIdx );
      }

      var firstName = getParameter('firstName');
   </script>
</head>
<body onload="function(){document.getElementById('nameplace').innerHTML = firstName; }">
  <h1>Hello <div id="nameplace"></div>, Welcome to my Vulnerable Page!</h1>
</body>
</html>

If you were to hit this page with the following URL: http://host.com/vulnerable.html?firstName=Chris

The resultant page would display: Hello Chris, Welcome to my Vulnerable Page!

However, what if you were to hit this page with a URL that looked like: http://host.com/vulnerable.html?<sript>alert('xss');</script>

You guessed it! You will get a pretty little popup. So what you say, server-side XSS controls can mitigate that risk easily, and you would be correct, however, what if the url looked like this: http://host.com/vulnerable.html#firstName=<script>alert('xss');lt;/script>

If you said that server-side mitigation wouldn't catch this, you are right! When a browser sends a request to the server, anything after the '#' is not sent as part of the request, as this is meant for browser control to jump to an anchor in the page.

So how do we fix this problem? Simple with ESAPI4JS - the page could be rewritten as follows:

<html>
<head>
   <title>My Vulnerable Webpage</title>
   <!-- Dependencies -->
   <script type="text/javascript" language="JavaScript" src="/js/esapi4js/lib/log4js.js"></script>
   <script type="text/javascript" language="JavaScript" src="/js/esapi4js/resources/i18n/ESAPI_Standard_en_US.properties.js"></script>
   <script type="text/javascript" language="JavaScript" src="/js/esapi4js/esapi.js"></script>
   <script type="text/javascript" language="JavaScript" src="/js/esapi4js/resources/Base.esapi.properties.js"></script>
   <script type="text/javascript">
      org.owasp.esapi.ESAPI.initialize();
      var firstName = $ESAPI.httpUtilities().getParameter("firstName");
      try {
         // Will throw an exception if there are multiple encodings in the value
         firstName = $ESAPI.encoder().canonicalize(firstName);
      } catch (e) {
         $ESAPI.logger('VulnerablePage').warn( org.owasp.esapi.Logger.EventType.SECURITY_FAILURE, e.getLogMessage() );
         alert( e.getUserMessage() );
         firstName = 'Guest';
      }
   </script>
</head>
<body onload="function(){document.getElementById('nameplace').innerHTML = $ESAPI.encoder().encodeForHTML(firstName); }">
  <h1>Hello <div id="nameplace"></div>, Welcome to my Vulnerable Page!</h1>
</body>
</html>

We have successfully mitigated DOM Based XSS attacks against our vulnerable page. Of course, in the real world, the vulnerable code will not be *quite* as obvious in most places, but the resolution is still the same.

Let's move on to the next piece, using ESAPI logging. You probably noticed the call in the above section of code to $ESAPI.logger

There are a few things to deal with when setting up logging for ESAPI4JS. The first is to pick your Logging framework. The Log4JS framework is used by the Reference Implementation and so that will be used for the first part of this demonstration. A subsequent blog post will discuss how to implement other logging frameworks into your ESAPI.

The first step is to setup your logging configuration. For the purposes of this example, we will only be setting up a single logger, and we will continue to use our vulnerable.html example from above. Without further ado:

Base.esapi.properties.logging["VulnerablePage"] = {
    Level: org.owasp.esapi.Logger.ALL,
    Appenders: [ new Log4js.AjaxAppender('/jsLog') ],
    LogUrl: true,
    LogApplicationName: true,
    EncodingRequired: true
};

// Since we specify that we want the application name logged in our configuration, let us give our application a name:
Base.esapi.properties.applicaton.Name = 'Vulnerable Application'; 

Now this will POST your log entry to the path /jsLog which should be mapped to some handler servlet or php controller on the server side. More details on using this appender can be found here

Now any calls to $ESAPI.logger('VulnerablePage') will go to this logger.

There are six methods for logging (trace, debug, info, warn, error, fatal) each with the signature .method( org.owasp.esapi.EventType eventType, String message, Exception exception );

You can define custom event types by instantiating new instances of the org.owasp.esapi.Logger.EventType class or reference the static predefined events

  • org.owasp.esapi.Logger.EventType.SECURITY_FAILURE - Used to log when something fails to pass a security control
  • org.owasp.esapi.Logger.EventType.SECURITY_SUCCESS - Used to log when something passes a security control
  • org.owasp.esapi.Logger.EventType.EVENT_FAILURE - Used to log when something fires an event, and that event does not complete successfully.
  • org.owasp.esapi.Logger.EventType.EVENT_SUCCESS - Used to log when something fires an event, and that event completes successfully.

Creating a custom EventType is simple.
var customEventType = new org.owasp.esapi.Logger.EventType( "Custom Event", false );

// ... later

$ESAPI.logger('VulnerablePage').info( customEventType, "Something happened!" );

HTTPUtilities

The HTTPUtilities object is meant to provide shortcuts for doing common tasks that have to do with the browser and the response. Right now, the available methods are:

  • addCookie( org.owasp.esapi.net.Cookie cookie )< - Adds a single cookie to the cookie jar/li>
  • getCookie( String name ) - Gets the String value of a cookie


  • killCookie( String name ) - Deletes a cookie if it exists in the current cookie jar


  • killAllCookies( String name ) - Removes all the cookies from the current cookie jar


  • getParameter( String name ) - Gets the value of a parameter on the URL



This should be enough to get you started using ESAPI4JS. I will make a seperate post at a later time going over the i18n framework.

Enjoy and feel free to share comments!

1.15.2010

ESAPI4JS - The new hotness!

So I have been hard at work on the ESAPI4JS code for the last couple of weeks, and have gotten it to a point where people can start to play with it. It will be in alpha for a bit yet, as not all the functionality is there, but here is a little of what you can do with it so far.

Download the script(s)
http://owasp-esapi-js.googlecode.com/files/esapi-compressed.js
http://owasp-esapi-js.googlecode.com/files/esapi.js

Import the Compressed or Uncompressed JS File on your page
<!-- Uncompressed Version -->
<script type="text/javascript" language="JavaScript" src="esapi.js"></script>
<!-- Compressed Version -->
<script type="text/javascript" language="JavaScript" src="esapi-compressed.js"></script>

Initialize the ESAPI
$ESAPI_Initialize();

Do some cool stuff!
var val = "<div&gt;Test</div>";
alert( $ESAPI.encoder().encodeForHTML( val ) );
try {
   alert( $ESAPI.encoder().canonicalize( val ) );
} catch (e) {
   alert( e.getUserMessage() );
}

I should be getting some documentation written up this weekend that explains how to configure the ESAPI for JavaScript and how to use the functionality that is complete.

In the meantime, you can see the source for the ESAPI4JS Encoder which is fully implemented.

If you are interested in getting involved in the project, shoot me an email and we will see how you can help out!

Development conversation about the ESAPI happens on the esapi-dev mailing list

User support is available on the esapi-user mailing list.

12.20.2009

Almost There - Sealed Objects in JavaScript

The last blog entry I wrote last week was a huge call out to anyone that could help me find the solution to the problem of writing secure objects is JavaScript. Unfortunately, the call went unanswered so I set out over the weekend to see if I could find the answer, and well, I haven't completely found the solution yet - but I am close.

Let me jump right into it:

Step 1 - We need to implement a "watch" function for browsers that don't support it
        Object.prototype.watch = function (prop, handler) {
            var oldval = this[prop], newval = oldval,
            getter = function () {
                    return newval;
            },
            setter = function (val) {
                    oldval = newval;
                    return newval = handler.call(this, prop, oldval, val);
            };
            if (delete this[prop]) { // can't watch constants
                    if (Object.defineProperty) // ECMAScript 5
                            Object.defineProperty(this, prop, {
                                    get: getter,
                                    set: setter
                            });
                    else if (Object.prototype.__defineGetter__ && Object.prototype.__defineSetter__) { // legacy
                            Object.prototype.__defineGetter__.call(this, prop, getter);
                            Object.prototype.__defineSetter__.call(this, prop, setter);
                    }
            }
        };

Step 2 - Now that we have that in place, we can create our seal method
        Object.prototype.seal = function() {
            for ( var e in this ) {
                this.watch( e, function(newVal,oldVal) {
                    var caller = arguments.callee.caller;
                    throw 'Attempt was name to alter a sealed object [' + this + '] from [' + oldVal + '] to [' + newVal + ']' + 'from [' + caller + ']';
                });
            };
        };
VIOLA!


That is it. This solution is currently working in FF3.5 and Chrome for Linux, I haven't gotten it to work at all in IE7 or 8 yet (Once again, thank you Microsoft) but I suspect once I throw this over the fence to some of the hardcore IE/Compatibility gurus at the office tomorrow, I will have the answer to that problem.

If you would like to see a working demo of this in action, you can checkout the demo page I put together for it at http://software.digital-ritual.net/js-secure-demo/.

I absolutely welcome any and all comments, and will test this out on more browsers as time permits tomorrow. Hopefully this could solve the problem, at least provided something doesn't stop the JavaScript RTE from running the Object.seal method on all objects that need to be sealed; but that is for load testing. For now this seems to be the best approach I can come up with.

12.15.2009

JavaScript? Hello? Is anyone there?

So I am still in the architectural design phase of ESAPI4JS, and have come across an interesting problem. Well, to be honest, there are lots of problems with JavaScript and trying to make it secure - but there is one that I have yet to find a way to overcome. This, in my opinion, is one of the biggest shortcomings of JavaScript that I have encountered to date.

On with the problem...

Say that you have a class that you are creating with JavaScript. You want to ensure that the "private" methods and properties of that class cannot be altered by code running in the same window.

This is a relatively trivial thing to do in javascript using closures:

var MyUnchangeableClass = function(){
   var MyUnchangeableClassImpl = function() {
      var _myPrivate = "Private";

      return {
         getPrivate: function() {
            return _myPrivate;
         }
      };
   };

   var _singletonInstance = new MyUnchangeableClass();

   return {
      getPrivate: function() {
         return _singletonInstance.getPrivate();
      }
   };
}

var unchangeableClass = new MyUnchangeableClass();
alert( unchangeableClass.getPrivate() ); // alerts 'Private'

Using a closure like this creates an interesting scoping situation where the property _myPrivate is locally scoped to the constructor and the 'Object' being returned by the function thus privatizing it both from the global scope and the scope of the closure itself. This scoping situation is called Closure Scope.

This is all fine and great, however, the top level globally scoped reference is always vulnerable to be altered. For instance, we know now that calling getPrivate() on the instantiated closure object will return the innermost value which happens to be "Private", but what happens if I alter the outermost globally accessible reference like this:

unchangeableClass.getPrivate = function() { return "Overwritten"; };
alert( unchangeableClass.getPrivate() ); // alerts 'Overwritten'

We have effectively subverted the entire point of the closure by substituting what the outermost function actually does (coincedentally, the references to anything Closure Scoped will disappear in this case as well, and will be ultimately GC'd, effectively removing the data from the Runtime entirely)

The one thing that is truly holding JavaScript back from being a language that has any hope in a secure world is the fact that there is NO RELIABLE way to SEAL an object. In Java, you can make a class final to ensure that the class cannot be extended to alter it's behavior, you can make properties and methods private to ensure that their behavior and values cannot be altered. There are similar strategies in just about every language that provides OOP or OOP-Like functionality (even PHP!).

I have come up with some somewhat hacky ways to accomplish this, but they can all be subverted by other code running the same runtime. I have even thought about creating a trusted JS plugin for browsers that basically keeps the JavaScript inside a sealed/signed jar after it has been downloaded (so processes outside of the browser cannot modify the cached javascript) and having the initial javascript source tell the plugin which object should be sealed, then have the plugins use the underlying C API to ensure that they cannot be changed. This is a huge undertaking and frankly is open to a ton of potential attacks.

The idea behind the ESAPI4JS library is good - basically providing end users with protection from server side code that has been compromised as a second level of defense. This is something that I think will become increasingly important as time goes on, but without the ability to create secure JS code that cannot be altered, it simply won't live up to it's full potential.

It will provide a second level of defense that can ultimately in most cases still protect the end user, afterall, the code to subvert the server-side code will be the main focus of the nefarious individual doing so, and they may not even realize that there is another layer of protection against potential front-end victims that also needs to be subverted.

I still think it is a great idea, and am excited to see where it goes, but I throw this out to the JavaScript community as both a challenge and a plea. This is something that JavaScript sorely needs (I am sure most JS library writers will agree) and the only way that we will ever see it is if the community demands it.

So Testify! To Securify!

Onward!