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.

1.13.2010

Firefox Plugins for Security Professionals - Best of 2009

Due to the overwhelming popularity of my first post back on my old blog called "Firefox Plugins for Security Professionals" ( apparantly it was even referenced in a book called 'Dissecting the hack: the f0rb1dd3n network' ) I have decided to put together a new list, highlighting the best security related plugins from 2009.

10. Fire Encryptor
The only reason this one isn't higher on the list is because it hasn't been updated to work with Firefox 3.5. However, it allows you to do quick realtime encryption, decryption, and hashing in your browser. Among the really useful scenarios where this comes in handy is when you are accessing a sensitive application on the web. You can enter a password that you will remember into the plugin, hash it, and use the hashed version of the password to login to the site.

9. Leet Key
Similar to Fire Encryptor, only this allows you to do realtime conversion to ROT13, BASE64, HEX, and URL encoded strings. Invaluable when working with injection attacks and trying to bypass filters in an application. For fun it also will convert any text into l33tspeak, morse code, binary, all upper, all lower, and BIN - as well as do simple DES encryption.

8. Tamper Data
Extremely useful plugin that allows you to tamper with a request just before it is sent to the server. Allows such useful things as changing headers (for request splitting fun), modifying POSTed parameters, adding parameters to a POST, adding/removing headers and other such goodness. You can guarantee that the bad guys are using this plugin, so you better be too!

7. ShowIP
Handy little plugin that displays the IP address of the server that you are actually on in the lower right hand corner of the browser status bar. Allows quick one-click access to whois data as well as the ability to copy the ip address to the clipboard for a quick paste into your favorite port-scanner.

6. Passive Recon
This is probably one of the most complete information gathering plugins that has ever been for a browser. A right click context menu allows you to find a wealth of useful and useless information about a target server. You can discover public services available on a server, all servers in the domain, what architecture the server is using, what commonly used ports are open, and a good deal more.

5. Hackbar
A CLI type interface for messing with URLs. This toolbar is mainly aimed at discovering SQL Injection flaws, but also has several built-in macros for XSS, Encryption, and Encoding flaws as well. Any serious analyst or security-focused developer should definately have this little gem in their toolbox.

4. Torbutton/FoxyProxy
Oldie but goodie! While the TOR network is by no means perfect for anonymizing internet traffic it is light years ahead of most every other easily accessible anonymyzer. TOR is one step down from a pwn'd proxy chain (although it is a very big step down) and although it is generally slower than molassis, if you are stealth scanning an application, it is extremely powerful and easy to use.

3. UrlParams
A quick easy access sidebar plugin that gives you complete access to all the POST and GET parameters on a request. Probably the most useful feature is the ability to replay a modified request to a new tab. It also gives you quick access to the referer header for black-hat SEO spamming if your into that kind of thing.

2. Web Developer
This plugin is an absolute MUST-HAVE for anyone using firefox to break applications. It puts a wealth of information about the current page at your fingertips. If you haven't seen this plugin you have probably been living under a rock for the last 5 years.

1. Firebug/Firecookie
Still at the #1 spot for the third year running is the Firebug plugin. Teamed up with Firecookie there is virtually nothing you can't do to a running webpage. Debug the javascript served from the server to find exploitable bugs, grep all the in memory javascript for evals, examine ajax requests and responses, monitor load times for time-based attacks, and on and on and on. Like the web developer plugin, if you have heard of at least firebug, chances are you have been living under a rock for the last few years!

That does it for my 2009 list. And they are all available as a collection from my shared collections on the Mozilla Add-Ons site:

Best of 2009 - Security Plugins

What are your favorite plugins?

A new type of security testing...

I am not sure if this is really a new idea, it probably isn't, but I haven't seen anything in the tubes about it and it is a concept that I have been slowly rolling around my brainpan while working on the ESAPI.

When we write unit tests for ESAPI, what we are doing is giving the API inputs and looking for the correct outputs, or looking for an exception. This is nothing new, this is what unit testing is really all about - but it is all based around business functionality.

My idea is to take that idea, of testing business functionality and apply the same philosophy to a new set of test cases.

Traditionally, there are 3 main types of assessments of an application to uncover security flaws:
  1. Vulnerability Scanning: This is usually the first step in an application assessment. It generally consists of an automated scanner, such as Nessus. If the assessment is being done by someone competent, it will also include a manual review of the site. The problem with vulnerability scanners is they are really good at finding the really obvious flaws, but they have no context to the application. The only way to do a full assessment of an application is to sit down in front of it and try everything you can to break it by hand.
  2. Static Analysis: There are some great static analysis tools out there that are great at finding common coding errors that lead to security flaws. For Java there are things like FindBugs and PMD. There are also services online that will scan the code in your repository for security related code issues. These can find some bugs that would otherwise be very difficult to find, but require a lot of tuning to limit the number of false positives that are reported.
  3. Manual Code Review: If you come into an existing application that already has an existing codebase, this can be one of the most daunting tasks you will ever encounter. Especially if you come into a codebase that has had a lot of hands in the pot (so to speak) with a lot of different coding philosophies. This process is exactly what it sounds like, sitting down in front of the code and analyzing every line of it looking for coding errors and bugs. To date, this is the most effective form of assessment, but it is rare for everything to be caught unless this process is implemented by a very good developer or architect from day 1 of coding.

What I am proposing is using the concept of automated integration testing in the runtime by writing code to test your code for security vulnerabilities.

Imagine the following situation. You have a simple guestbook web application. The application consists of a single JSP file, a servlet and a facade that sits in front of a DAO. Let's illustrate this with some pseudo-java below.

Value Objects to represent the data
public class Entry implements Serializable, Comparable<Entry> {
   private long id;
   private String message;
   private String fromName;
   private String fromEmail;

   // ... declare getters and setters
}

Data Access Layer
public interface GuestbookDAO {
   List<Entry> getEntries() throws DAOException;
   void saveEntry(Entry entry) throws DAOException;
}

public class MySQLGuestbookDAO implements GuestbookDAO {
   public List<Entry> getEntries() throws DAOException {
      Connection con = null;
      try {
         List<Entry> entries = new ArrayList<Entry>();
         con = JDBCHelper.getConnection();
         Statement st = con.createStatement( "select * from entries" );
         ResultSet rs = con.executeStatement();
         while ( rs.next() ) {
            entries.add( new Entry( rs.getLong(1), rs.getString(2), rs.getString(3), rs.getString(4));
         }
      } catch (Throwable t) {
         throw new DAOException(t);
      } finally {
         if ( con != null ) con.close();
      }
   }

   public void saveEntry(Entry entry) throws DAOException {
      Connection con = null;
      try {
         con = JDBCHelper.getConnection();
         PreparedStatement st = con.createPreparedStatement( ... );
         // ... standard jdbc code
      } catch (Throwable t) {
         throw new DAOException(t);
      } finally {
         if ( con != null ) con.close();
      }
   }
}

public class GuestbookDAOFactory {
   public static GuestbookDAO getDAO() {
      return new MySQLGuestbookDAO();
   }
}

Facade
public class GuestbookFacade {
   private GuestbookFacade() { /* Singleton */ }
   private static final GuestbookFacade myInstance = new GuestbookFacade();
   public static GuestbookFacade getInstance() { return myInstance; }
   private static final Logger log = Logger.getLogger( GuestbookFacade.class );

   private final GuestbookDAO dao = GuestbookDAOFactory.getDAO();

   public List<Entry> getEntries() {
      List<Entry> out = new ArrayList<Entry>();
      try {
         out = dao.getEntries();
      } catch (DAOException e) {
         log.error(e);
      }
      return out;
   }

   public void saveEntry(String message, String fromName, String fromEmail) {
      Entry entry = new Entry( message, fromName, fromEmail );
      try {
         dao.saveEntry(entry);
      } catch (DAOException e) {
         log.error("Unable to create entry: " + message + ", from: " + fromName + "<" + fromEmail + ">", e);
      }
   }
}

Controller
public class GuestbookServlet extends HttpServlet {
   public void doPost(HttpServletRequest req, HttpServletResponse resp) {
      String action = request.getParameter( "action" );
      if ( "SAVE".equals( action ) ) {
         String message = request.getParameter( "message" );
         String fromUser = request.getParameter( "fromUser" );
         String fromEmail = request.getParameter( "fromEmail" );
 
         GuestbookFacade.getInstance().saveEntry( message, fromUser, fromEmail );
      }

      List<Entry> entries = GuestbookFacade.getInstance().getEntries();
      request.setAttribute( "entries", entries );
   }
}

View
<html>
<head><title>Guestbook</title></head>
<body>
   <%
      List<Entry> entries = request.getAttribute( "entries" );
      for ( Entry e : entries ) {
   %>
   <div class="entry"><%= e.getMessage() %> - From <a href="mailto:<%= e.getFromEmail(); %>"><%= e.getFromUser() %></a>
   <%
      }
   %>
</body>
</html>

This is a very basic application (that is full of security flaws I might add, but we will ignore that little tidbit for now and let our test catch them) that we will now write an example SecurityTestCase for.

public class SecurityTestGuestbook extends TestCase {
   private MockHttpServletRequest request;
   private MockHttpServletResponse response;
   private HttpServlet servlet = new GuestbookServlet();

   public void setup() {
      request = new MockHttpServletRequest();
      response = new MockHttpServletResponse();
   }

   public testSQLInjection() throws Exception {
      final String[] injections = new String[] { "' or 2=2--" };
      request.initialize();
      response.initialize();
      request.setParameter( "action", "SAVE" );
      request.setParameter( "fromUser", "Beef" );
      request.setParameter( "fromEmail", "email@domain.com" );
      for ( String test : injections ) {
         request.setParameter( "message", test );
         try {
            servlet.doPost( request, response );
            fail("No exception thrown - SQL Injection Possible" );
         } catch (Throwable t) {
            // Success
         }
      }
   }
}

This is just a single quick example, but it illustrates the point nicely. We will leave verifying functionality works to our standard unit tests, but write another test suite specifically to test your security controls. You should probably have more granular tests that just testSQLInjection - maybe testRequestSQLInjectionMessage, testRequestPersistentXSSMessage, etc.

I would love to hear what people think about this as a development concept, especially those who work in TDD and Agile environments. I would also be interested to hear from people who have used some of the macro based front end testing tools to see if they have created similar view test suites.

Cracking Passwords with Teh Google

Have you ever googled yourself? You may have to sift through several pages of results about people with the same name that aren't you, but you would be surprised how easy it is to find a wealth of information about yourself by combinging information retrieved by your social networking profiles being indexed.

Have you ever tried your hand at cracking a password? Chances are if you have, you have downloaded a word list and may have eventually cracked a password (unless you happen to have a cluster of PS3's laying around to do all the processing for you)

Password cracking is a lost art that often requires a lot of patience. There are two primary methods of cracking passwords: online and offline. When you attempt to crack a password online, it is often via a 'brute-force' style attack and has to be throttled carefully to avoid immediate detection (although, any competent system admin will be able to spot an online BF from a mile away after 10 shots of tequila) Offline, is often much more difficult to accomplish, simply because in order to crack a password offline, you either need to obtain a password list, or at bare minimum the hash of the password that you are trying to crack.

All that aside, one of the most difficult and time consuming parts of cracking passwords is starting with the right wordlist. There are tons of really horrible wordlists spread all across the internet, and even a handful of good ones. I am fairly partial to the Common Passwords Dictionary and the extremely large dic-0294 when I am flying blind.

However, with the wealth of knowledge available on the internet about everyone you know from sites like facebook, myspace, linkedin, hi5, twitter, and the list goes on and on, there really is no need to fly blind anymore when cracking passwords.

Now before I go much further, let me warn you that this is a tedious process right now as I am not aware of any tools in the tubes that do this for you (although, such a tool probably would not be to difficult to build) Also I would like to note that as a security professional, the information that I am providing is as much a warning to people about how easy it is to get their password, as it is a informative post about something that has been sorely neglected in security presentations (that I have been privy too).

To keep this relatively brief while still getting the point across, the example I am providing below is purely fictional, and any similarity to actual people is completely unintentional.

Step 1: Recon
If you personally know your target, this step is pretty much already done - however, if you don't know the target, the first step is to find out some very basic information about them. This is all public domain information that is easy to gain through the use of search or social engineering. For the purpose of this example we will say that I am trying to crack the password of a coworker named Don Johnson.

Now I know very little about Don other than the company he works for (obviously) and the department that he is in. We will say that he is the director of Human Resources. Our fictitious company name will be Acme Inc.

So seeing as how I know about him only in his job, LinkedIn seems the obvious starting point for me. Now, LinkedIn is one of those funny psychological experiments that proves that people really don't care about their privacy, no matter what they say. Their profile may say that they are only interested in reconnecting with previous coworkers, but if a recruiter requests to be in their network, they will almost always click - if nothing else, for curiosity sake.

Google Search #1: site:linkedin.com "Don Johnson" +Acme +Denver

9 times out of 10, the Don Johnson we were looking for will be in the top 5 results returned from google. Once I have found his profile, it is quick and easy to get a free gmail account, create a fake recruiter profile on linkedin, and start adding a bunch of people, with Don among those being added. The reason for adding several people is that Don may be a little paranoid and if a recruiter with no network requests to be in his network, he may think twice about allowing him - however, if Don sees that this recruiter is acting like most every other recruiter on linkedin, and obsessively adding 10-20 people a day, well he will probably think nothing of it and allow the request. Once he is in your network you can view his full profile which will often include such information as all of his prior employers, education, blogs, etc. Generally, I will take a scrape of the entire profile (a scrape can be as simple as using File -> Save Page As in your browser) and use the information and picture from that profile to identify him on other networks.

Let us say that in the recon of my target I discovered a linkedin, facebook, myspace, and pandora account all linked to Don. I have scrapes of his profile pages from each network, along with an archive of comments and wall postings on friends profiles from the last 60 days.

Step 2: Assimilation of Information

This is where things really start to get interesting. You have a wealth of information now about your target. You know who he is dating, the names of all his pets (real and virtual), a list of his favorite musicians, movies, and books (invaluable), a collection of nicknames, his birtday, and much much more.

I specifically call out the fact that music, movies, and books are invaluable information to know about a target. Often, people will use a term or character name from their favorite stories as all or part of their password. So that being said, you can take Don's favorite songs look up the lyrics and start your wordlist. Next, look up a character list from his favorite books and movies, then lookup memorable quotes from those characters (imdb.com) and (wikipedia) are your friends here. Keep doing this with all the information you have until you have a comprehensive word list built specifically around the social profile of your target.

This is it, this is all you need to do. I have a relatively high (60-70%) success rate when building a custom word list using this method and if I were to take the time to build some tool that used the full power of the internet to build related information, I could almost guarantee a 90%+ success rate at using this method.

So the next time you are updating your profile on myspace or facebook, think about the password that you are using to login to that site and see if you can connect the dots between your password and any of the information on your profile. I would say that for most people, they will be able to make the connection fairly quickly and most of the time.

I purposefully described this process in a fairly abstract manner, as it is a very effective means of social engineering without having any direct contact with the target, and really, there are enough bad guys in the world already.

We rely on technology to keep our personal information secure and safe, yet the true dangers still lie in the information that we publicly disclose without a second thought. This is no different from the days of dumpster diving, only google is a much cleaner and organized dumpster.

1.11.2010

What is the ESAPI?

It has been great to see so much buzz about the OWASP ESAPI in the tubes lately. It is very exciting for me to be involved in a project that has people excited and even more important it is fantastic to have people evaluating it and pointing out where it needs work. This is some of the most invaluable feedback a developer can get!

That being said, I have seen some questions floating around to the effect of "Why use ESAPI for authentication and access control when we already use *insert framework here*?"

This is a very valid question, and I think that some people may have gotten the wrong idea about what the ESAPI is really trying to accomplish.

There are some fantastic frameworks out there for logging, authentication, cryptography and all the things that the ESAPI does, and it is not the intention of the ESAPI to replace these frameworks, but rather to provide a central interface for developers to access the functionality of those frameworks in a simple fashion.

While we provide a reference implementation of ESAPI, a good deal of the code provided is to provide an example, or a plug and play environment for the ESAPI itself. It is not only intended but even reccomended that if you are using the ESAPI in a production application, that you use the pieces of the reference implementation that work for you, but also create wrapper objects to use your existing security controls through the ESAPI. This provides several things that are deeply important to having a secure application, especially in an agile environment.

  1. Provides a standard and central API for developers to access security controls which makes the job of the developer simpler. If the developer knows that anytime he needs to log a user in he should call ESAPI.authenticator().login( request, response ) it makes it easier to remember and easy to implement.
  2. Decouples the application from the security frameworks in use. This is probably the most important piece of the puzzle, at least in my mind. Things like access control checks, output encoding, and logging are sprinkled throughout the entire codebase of an application, which makes it a very painful process to migrate to a new framework if you ever need to. Imagine you have an application which consists of several hundred class files and and several hundred JSP files. One day you decide that you want to migrate from using Spring ACEGI to JAAS. You now have to change the code in every class file where you access that library to use the new library. If you were using the ESAPI, you would have a wrapper implementation of Authenticator and AccessController that delegated to your framework. Now you just have to write a new wrapper class and change a properties file and your job is done!

It has been said that ESAPI should be used to "fill in the gaps" where other security controls do not work, such as output and input encoding. I think that should be rephrased to reflect the Reference Implementation of the ESAPI and not the ESAPI itself.

That being said perhaps it would be helpful if there was an incubator project under the ESAPI umbrella that provided wrappers for the more popular frameworks. Having that could allow the developers have the ability to drop in the ESAPI then use wrapper jars as *plug-ins* to the API. So if you were using JAAS under the covers for your authentication and access control framework, you could drop in ESAPI.jar and ESAPI-JAAS.jar into your classpath, update your ESAPI.properties to use org.owasp.esapi.provider.authentication.JAASAuthenticator and you are off to the races.

What do you think?

1.09.2010

More on Context Based Access Control

So I have been doing some thinking about how a good way to implement a context based access control system might look. The one thing that keeps breaking interface is how exactly does one define a context in terms of code. Then it came to me, what if context was not defined in terms of code at all, but was defined in terms of a natural parsable language?

Let's start at the beginning, first let's talk about what the interface for this CBAC might look like. Since my last post on this subject used java, I will continue with that language:

public interface AccessController {
   boolean hasAccess( User u, Request request, Context ctx );
}

Pretty simple interface I would say. And pretty self explanatory to boot. Now, to define the parameters. User is obvious, this is the user making the request. Request is the request itself and the pertinent details of the request. Context is the tricky one to define here, but perhaps the interface will make things a little clearer.

public interface Request {
   String getAction();
   Object getParameter(String key);
}

public interface Context {
   T getSubject();
   void setSubject(T);
   User getRequestOnBehalfOf();
   void setRequestOnBehalfOf(User u);
}

The Subject is a generic reference to the subject of the request. For example, the subject could be a Customer record or a MenuItem on the UI. You'll notice that I have also introduced the idea of performing actions on behalf of another user. This is something that I think is lacking from most AC implementations, and is something that is very important. To illlustrate let's take the example of a Medical Records System in a hospital. HIPAA places strict rules on who has access to a patients medical records. Although I am not 100% up on what all the rules around this are, let's say for example that only Patients and their physicians (any physicians that have seen the patient and thus added records) shall have access to that patients records. This is fine and great, but when a patient walks into the medical records department and wants their records, should we just have them sit down at the desk and fetch them by themselves? This is probably less than ideal. A Medical Records employee will probably need to get those records on behalf of the patient. Now, the flipside is that we don't really want to allow any old MedRecs employee to be able to pull up all the information about any patient at any time they want. So really what we need is a 2-tier access control check that not only checks the requesting employee is in medical records, and that the request is made on behalf of the patient; we also want to verify that the patient has indeed approved the request for the employee to access their records. So, perhaps there is an approval code, for simplicity sake, we will say it is the last 4 digits of the patients SSN, and for the Medical Records employee to access that patients records, the patient will have to authorize the transaction by entering the last 4 of their SSN on a keypad on the counter.

I dare you to show me a RBAC system that solves that problem. :)

This is where we get into the rules part of the system. This is the part that I am most excited about, as not only is it the most complex part of the system, but the answer is so simple. Let's dive right into it:

define action ACCESS_PATIENT_MEDICAL_RECORD {
   # The requesting user is one of the patients physicians
   User in Patient(Physicians) OR
   # The requesting user is the patient logged into the web access system
   User is Patient OR
   # User is a MedRecs employee on behalf of the patient with patient authorization
   (User on behalf of Patient AND User in Role(MedRecs) and Request(AuthCode) is Patient(AuthCode))
}

Kinda pretty isn't it?

While this is by no means the complete solution, I feel like it has promise as a system that is not overly complex to implement but allows the flexibility that a true CBAC needs to allow.

I would love to hear your thoughts on the subject, so share!