CSRF - How much is enough?

One of the hot topics at AppSecDC this year seemed to be CSRF attacks and protecting against them. CSRF was brought up at least once in virtually every session that I attended at the conference (including several questions in my own ESAPI Presentation)

This spawned some great hallway conversations and got me really thinking about how we solve CSRF issues today. I kept coming back to an application I was working on recently that uses GWT and how I had to solve CSRF for that particular situation. See, normally the solution is to append a parameter on to the GET or POST request with a unique token that the server can verify against. Depending on who you talk to - sometimes this token has a lifespan of a session, and sometimes it is only a single request. Some would argue that for more sensitive applications you should use a per-request token and per-session tokens could be used in other places.

With that in mind, let's look at the GWT problem. You see in GWT, everything is handled by the Java -> Javascript compiler; which makes it very easy for Java Developers to create Rich UI Webapps. The flipside to this is that there is very little visibility (without a lot of research) into what is actually happening to your java code when you use GWT. Most developers just know that they put Java in and get a web app out.  This presents an interesting dillema for security in general, but specifically for things like CSRF and DOM Based XSS.

Google has posted an article all about securing GWT Applications - while I normally commend google on their suggestions as they pertain to security in software, I could not believe what they were suggesting as a solution to CSRF. The full article can be read here - but here is an excerpt outlining the proposed solution.

"A common countermeasure for XSRF attacks involves duplicating a session cookie.  Earlier, we discussed how the usual cookie-based session management model leaves your application open to XSRF attacks.  An easy way to prevent this is to use JavaScript to copy the cookie value and submit it as form data along with your XMLHTTPRequest call.  Since the browser's Same-Origin Policy will prevent a third-party site from accessing the cookies from your site, only your site can retrieve your cookie.  By submitting the value of the cookie along with the request, your server can compare the actual cookie value with the copy you included;  if they don't match, your server knows that the request is an XSRF attempt.  Simply put, this technique is a way of requiring the code that made the request to prove that it has access to the session cookie."

Wait... what?

First thought that popped into my mind when I read that (and maybe you had the same thought) was that the proposed solution of duplicating a session cookie doesn't solve the problem at all. I suppose this could be the case in a Framejacking CSRF Exploit, that this would solve that issue - but if I send a crafted link to a handful of users to their bank to transfer 1 million dollars to my account like:

"Dear Sir or Madam, I am writing you from EvilHacker Bank and Trust to let you know about a new policy regarding our interest rates - please click the evil link below to get pwned.
Doctor Evil
EvilHacker Bank and Trust"
How does a cookie protect the user who is possibly already authenticated to the EvilHacker Bank application with a session cookie in their browser (and said duplicate session cookie). The browser is going to send both cookies because it does in fact, have access to them.

Well, that's completely unacceptable, I thought to myself. That doesn't protect the application or users of the application at all from CSRF. So I set out to come up with my own solution.

The answer, which turned out to be quite simple after a lot of research into how GWT builds in RemoteService interfaces and the javascript it uses to call services exposed to the client, was to make a slight modification to the ProxyGenerator (creates a Proxied implementation of the RemoteServiceAsync interface created by the developer). If you think of GWT Services in terms of RPC's this should make sense. I will likely post a follow-up detailing the solution and how to integrate it, but the meat of it is really this:

  1. App Server needs a filter or some means to setup the session on the first request made to the application. This is standard CSRF protection behavior. 
    1. Caveat with GWT - GWT generally uses static HTML files and the Javascript generally doesn't have any reference to any existing interpreted code (ie: JSP, PHP, etc.)  So the question became how do I tell the client application what the CSRF token should be. I chose to go with a cookie, but this could also be done as a separate RPC call to get the token (this presents it's own set of problems - they are not overcome-able) 
      1. Created a filter (CSRFFilter) to generate a CSRF nonce when the session is created and set that as a cookie that gets sent back to the client. 
  2. Client application reads the nonce from the cookie and alters the request to add a custom header containing the nonce. 
  3. Server checks for either the presence of a request parameter or request header containing the CSRF nonce and verifies it against the value stored on the session (not in the cookie)
  4. A new nonce is generated every time a new session is created.

So what does this really mean?

It means that since SOP rules won't allow a Java Applet (post 1.6 update 8) or Flash App (unless it is setup completely incorrectly) to make a cross-domain request - you are safe from the attack embedded in a flash or java applet, and since an e-mail client can neither predict the nonce, nor can it send request headers - you are safe from CSRF.

It also means that you cannot have entry-point actions in your application. So if your model is to allow people to accomplish some action by clicking a link from their e-mail - you will want to exclude that service from this solution (or just about any other CSRF protection - here you have are probably going to have to resort to a hash that can be calculated as your CSRF nonce, which still provides ample protection against most threat agents and situations, but is slightly less evil-hacker-proof then using something completely random)

Now on to the argument about sensitive data and the per-request token model. I think this is severely overcomplicating an otherwise simple and elegant solution. A distributed phishing style CSRF attack would have to not only count on a pre-authenticated session but would also have to predict the nonce (which is tied to the authenticated session) which while not completely impossible is so improbable that it equalizes the threat completely. In other words, with this solution - you may have a single successful attack inside millions of years (depending on the width and PRNG used to create the nonce)

The complexity introduced in managing a per-request model in an Ajax application becomes a nightmare full of bugs.

So, in summary - I contest that the per-request model of CSRF nonces is overcomplicated and a complete overkill in 99.9% of cases (there may be the small edge-case where this makes sense).

Remember, the more complicated a Security Control is - the more likely there is a bug in the control that can be exploited to circumvent it.


Call To Arms: ESAPI Documentation Team!

We are in desperate need of some people to aid in updating and completing the documentation for ESAPI 2.0GA Release (upcoming).

If you are a technical writer, or interested in writing at all, we could use your help! After all, how many of you would actually want your developers to also write your technical documentation?

That being said - here are the primary areas we are looking for help with documentation:

  1. Installation and Configuration
    This area of the documentation has been done and done again, but still needs to be clarified and updated to reflect changes in 2.0 and consolidate some of the developer documentation (crypto) into the core documentation.
  2. Integration
    This area of the documentation needs a lot of love and attention. This area is also the least defined as far as what goes here. I envision a basic outline of:

    • Integrating Core Componenets (Encoder, Logger, Validator, etc.)
    • Extending Core Components (Adding custom validators - etc.)
    • Creating Adaptors (Authenticators, Access Control, etc.)
    • Integrating with Popular Frameworks
      • Spring
      • Struts
      • Grails
      • GWT
      • etc
  3. Real-World Solutions
    Collection of Examples of how to solve real issues encountered in applications

These are only a few that I could think of off-hand, so if you are interested in helping - get in touch with us on the ESAPI-Developers or ESAPI-Users Mailing Lists and let us know. You can always get a feel for what we have already by visiting the wiki at The ESAPI Homepage.

Dave Wichers has offered to head up this effort and work on a documentation roadmap - and he has been with the project since the beginning offering thoughts, patches, and guidance.

Cross Pollination; it's not just for bees...

While I was at AppSecDC 2010 - I got into a great conversation with John Steven from Cigital about a great number of things. One of those, and something that I have been openly preaching for years now, is the need for the developers and security professionals to start talking to each other, start interacting, and most importantly start teaching each other.

There are a select few people, like myself, that are kind of double-agents. I have spent the last 5 years as a Senior Software Engineer and I did security - now I am an Application Security Engineer and I do development. At no one point in time have I seen these as opposites, and I think they compliment each other quite well.

What I would really like to see in both communities is people branching out and not only learning but working to solve problems in both. Developers attending security conferences, giving talks at security conferences about subjects like agile/xp, build systems, continuous integration, frameworks, and writing good code - conversely security professionals at development conferences, giving talks on code review, security testing, tools and frameworks, and giving cool demos.

I have started to see this adopted slowly by both OWASP conferences and the NFJS tour. Uberconf had a day long track that was almost purely security related information - but we need more community involvement. It is hard to justify an entire track dedicated to development at an OWASP conference if there will only be 5-10 people attending it. It is up to the community to start expressing an interest in this concept of cross pollination.

I envision a conference with the following people attending:

* Developers
* QA Analysts
* Security Engineers
* Configuration Managers
* IT Managers

And the following tracks:

* Development and Architecture
* Offensive Security
* Defensive Security
* Metrics and Reporting

Moreover, I would love to see more coming out of these tracks then just a bunch of people sitting around talking. I want to see people actually working together to accomplish things. Presenters designing a project that can be done - or taking an existing project and working on it.

It's funny because almost every conference I have been too - I almost always think to myself, here we have a building with 100-200 of the smartest people in and we are missing the opportunity to build things - make cool new discoveries - and invent technologies.

After my conversations with John last week I am convinced that we can start to make some of these things happen and a couple of us have already taken the first steps in putting some pretty cool ideas together.

If you would like to see this happen too, raise your hand - we can always use more people in the community bringing in new voices and ideas.


Whats new?

So - as you may have noticed, it has been a while since I have posted on my blog. There is a good reason - a lot of things have been changing and there are lots of wheels and cogs spinning all over the place right now. But I do have some updates and now that the dust is starting to settle, I will have the opportunity to post more regularly again.

First order of business, after a great 5 years at ServiceMagic as a Software Engineer, I have decided to take the next step in my career and accepted an offer from Aspect Security. This actually occured over a month ago, but as I said - things have been a little crazy. My new official job title is Application Security Engineer, and I will be working on a lot of really cool things at Aspect Security. I am excited to see where my new path takes me and looking forward to becoming more and more involved in Application Security.

Next order of business, OWASP and specifically ESAPI. I was recently (along with Kevin Wall) promoted to be a Project Manager of the ESAPI projects - and I have set some pretty high goals for myself with the project. Some of these goals have already been realized, however, there is still a great deal to be done. Here is a high-level overview of some of the things that I am working on right now with the ESAPI project and some things that are done -

1. ESAPI distribution in Maven Central.

You may have seen my tweets regarding ESAPI now being available from Maven Central. This was a huge step for the team and something that was desperately needed. There are a lot of large projects out there using Maven for dependency management, and with the somewhat complicated footprint of ESAPI - it was a fairly painful process to get it integrated into large projects that were using Maven (or anything else that using Maven repositories)

Now, you can integrate ESAPI into your Maven project painlessly and without having to worry about manually managing the dependencies and deploying them into your local repository.


Repository management has been graciously shared by Sonatype OSS.

2. Continuous Integration

I am currently working with the guys over Coveros on getting a public instance of SecureCI setup to handle our continuous integration needs. The instance will be hosted on Amazon EC2.

The idea behind this is that having continuous integration will solve 2 distinct problems with ESAPI:

  1. Transparency
  2. Regular Releases

Both of these topics are, IMHO, integral to the success of any open source software project of ESAPI's size. By using continuous integration we will be regularly running our full test suite against the ESAPI codebase (nightly) and making the results of those tests publicly available - thus addressing the concern of transparency. To address the concern of regular releases, the CI process will push a nightly snapshot of the ESAPI build to the Snapshot Repository on Sonatype.

3. Alignment of the API's

One other large undertaking is to get all of the various language implementations in-line as far as the API itself. The concept here is that I should be able to define a set of language agnostic tests that verify that an implementation of ESAPI conforms to the specification (which also needs to be defined in a cross-language format)

In the past, each language has implemented the ESAPI in whatever way they saw fit to do so - which worked well when ESAPI was still in it's infancy - however, as the project grows it is imperative that the interface be well defined and tests can be run against an implementation of a specific control to validate the control performs as expected. This will become increasingly important as the codebase continues to grow and users integrate the API with other frameworks and tools (Spring Security, Struts Validators, Siteminder Authentication, etc.)

4. Splitting at the seams

Another sensitive issue in the Java implementation is the footprint of the ESAPI. A great deal of implementers are using pieces and parts of ESAPI to solve specific problems, and as such there are a large amount of dependencies that are quite simply taking up space. I aim to split the ESAPI into it's core functionality that will consist of the interfaces designed to specification and what is considered to be the core functionality of the existing reference implementation - ie. Encoders, Validators, Logging, HttpUtilities.

As you can probably guess, none of these goals are small and quick to be realized and there are a lot of issues yet to be resolved in getting them implemented. I will be posting updates here as things come to fruition.

Last order of business - I was given the opportunity to present my talk on Solving Real World Problems with an ESAPI at AppSecDC last week and the reception of the talk was fantastic. I got some great feedback from people looking to use ESAPI for their clients and in their code and had some great conversations with people regarding where ESAPI is today and where it is going in the future. If you would like to see the slides (and video coming soon) of the talk - they are available from the AppSecDC Schedule Page.

That is all for now, but watch my Twitter Feed and blog for additional updates over the next several months!