Rails, Django, and Just-Barely-Enough CSRF Protection

This week I found what I thought was a bug in Rails 2.3: it does not check the anti-CSRF authenticity token for AJAX requests. Due to years of experience with Rails I knew that this was not the previous behavior I have come to expect, so I dug around and learned that this behavior was intentionally changed some months back. Due to same-origin policy for XMLHttpRequests, the existence of the X-Requested-With header is considered sufficient validation of the request. Some details of the commit and comments on it can be found following this Github link. Much thanks to my friend Cory Scott of Matasano for bringing this to my attention.

Okay, fine—sort of. I have a beef with this.

Good security practice is about implementing layers of security, and this flies in the face of that. If certain other vulnerabilities are present, the most obvious one being HTTP response splitting, then CSRF is once again possible. Any vulnerability that could allow custom headers to be inserted in a CSRF request now makes them possible because the authenticity token is bypassed by a custom header.

In my opinion, if a site has data worth protecting with an anti-CSRF authenticity token, there’s no reason not to use it for all requests that can alter that data. Doing the bare minimum is what I call Just-Barely-Enough Security.

Note that Rails 3.0 handles CSRF protection differently (within Rack), and I have not examined it; the above comments apply only to Rails 2.x.

So it turns out that Rails is not the only web framework out there where the CSRF protection was in the just-barely-enough category. I have also been working on a Django 1.1 project recently, and in doing so I have found another category of just-barely-enough security (fixed in Django 1.2). Django 1.1 generates the authenticity token in a somewhat weak manner, but it is not weak enough that it is exploitable by itself. The weakness is that the authenticity token is the MD5 hash of a site-wide secret concatenated by the session ID (in contrast, Rails 2.3 and Django 1.2 generate a completely random token for each session). Because of how MD5 hashes are computed, an attacker could potentially learn the state of the MD5 computation up to the point of hashing the site-wide secret and himself compute any authenticity token given a session ID without further consulting the Django server. However, this is not an issue by default because Django’s session fixation protection prevents it from responding with session IDs that it did not generate, so the attacker cannot build up the necessary information to perform the attack. But if something were to be configured wrong on the Django server and a session fixation attack were to be possible, then the attacker would have more avenues for exploitation than just using session fixation on the victim directly.

Even worse would be a situation where the session fixation issue was found and repaired, but not before an attacker gleaned the necessary information to generate authenticity tokens for the site. The site administrator would think he closed the security hole, but his site may still be exploitable based on previously leaked information. That would be rather unfortunate.

Thoughts on Pair Programming

I have recently been exposed to the first pair programming in my career, and I want to quickly share some thoughts on it.

Honestly, at first I found it a little frustrating. There I was spending half my time watching someone else implement some stuff, and my brain simultaneously stuck elsewhere solving world hunger while trying to be “helpful” to that other guy with me. It took a few weeks before the benefits really started dawning on me and also to appreciate the contribution I make when not the guy with the keyboard. I think many people have recounted much of what is great about pair programming, but the one that I have not heard that really makes me giddy is that your partner prevents you from being lazy.

In particular, I do not mean that your partner prevents you from using things like email as a distraction from getting stuff done (another benefit that others have recounted). Instead I mean that when you are racing to complete a programming task and you encounter a decision to: (1) hack it and jam something in place quickly, or (2) Doing It Right but burn up extra time doing so. Without a partner you typically choose #1 while lamenting that you did not choose #2. You add to your technical debt and bad karma and you are ridden with guilt; it is a double whammy!

With a partner, what happens instead is that you suggest #1 to your partner, but regardless of whether your partner can discern whether #1 is Doing It Right he can see your hesitation and draws your thoughts out of you about #2. Before you know it, he is excited to see you through to Doing It Right! Your heart leaps in joy and later, when you go home for the day, you smile just a little more when your sweetheart asks, “how was work today, honey?” :)

Rise of the Mammals

It is 2009, and it looks like the sky is falling. Perhaps it is, just a little. I think it is a good thing. How can I say that as people are losing their jobs? It is easy if you look at what will bring the greatest good to the greatest number of people. For too long our economy has suffered at the hands of large, lumbering creatures that do not care one whiff about you or anyone else—cold blooded monsters that would stab you in the back and kick your rotting corpse to the curb the minute it thinks you missed a payment due to its own poor accounting practices. I call these companies the dinosaurs. Those that will suffer the most in this down economy are the dinosaurs.

As the dinosaurs continue to fall, the need for the goods and services they have been providing up until now will not disappear. The people that previously fed the dinosaurs (customers and employees) will have new opportunities to feed another kind of creature that has always been around here and there but will explode in numbers to take care of the things dropped by the dinosaurs. These creatures are the mammals.

Mammals are good for economies. Most of them are small, light on their feet, and they are warm-blooded. They do not create a “Customer Loyalty” program to pretend they care; they actually do care, and that care is felt person-to-person in the dealings of business. Because mammals are typically smaller than dinosaurs, it is easier for them to operate closer to home. Your money stays local instead of going to Washington or New York. In the good times when Washington and New York are flush with cash, the dinosaurs are happy to re-invest it everywhere. As times turn ugly, they will cling onto your cash and your locale will see nothing coming back. This is why it is so hard to find a loan these days, even if your credit worthiness is really good.

I urge people to not wait for the dinosaurs they feed to collapse, but to invest today in the mammals available in your area. Your money will be going towards making your local economy more robust and better able to provide new jobs in your area as the dinosaurs continue to release personnel. Times will be tough for the next year or two, but in the end I want to look back at this time as the time of opportunity—our time for building a new kind of economy that will take care of us for time eternity.

Let me repeat one thing before I sign off: invest in your local mammals today. Feed them now so they will be strong enough to feed you back when you need them.

AVLTree 0.1.4 Released

This morning I released AVLTree version 0.1.4. The difference from version 0.1.3 is an idea from modifications made to the code by the Samhain folks to improve performance.

If you are not familiar with my AVLTree project, it is a C library that implements AVL trees and provides an interface for indexing and iterating over objects. I like to think of it as my little C answer to the hashes and dictionary objects available in more advanced languages.

Templating in Excel

I wrote a little spreadsheet template language for Excel VBA (Visual Basic for Applications). What for? Say you have a report you create often, and you’re thinking of making a macro in Excel to help automate its generation. You want to report on the sales of your widgets from multiple locations, and you already have a template in mind for how the report should look:

Template of Widget Report in Excel

Template of Widget Report in Excel

I thought it would be so nice to be able to do this that I wrote the VBA to do it. I call it TemplateKicker. To use it, I copy the TemplateKicker module and the TemplateKickerVariables class module into my spreadsheet from TemplateKicker.xls (this file also contains the example shown here). Then I write a macro to insert the values for each location I am reporting on:

Public Sub Widget_Report()
    Dim Vars As TemplateKickerVariables
    Dim LocationIDs As Variant
    Dim WidgetSales As Variant
    Dim Index As Integer
    
    LocationIDs = Array("A-12345", "B-22222", "C-33333", "D-2R2", "E-5555")
    WidgetSales = Array(34, 12, 15, 6, 39)
    
    Set Vars = New TemplateKickerVariables
    For Index = 1 To 5
        Vars.SetVar "location:" & Index & ".id", LocationIDs(Index - 1)
        Vars.SetVar "location:" & Index & ".widgets.sold", WidgetSales(Index - 1)
    Next Index
    
    KickWorksheet(ActiveWorkbook, Sheets("Sheet1"), Vars).Name = "Widgets"
End Sub

One run of the macro later, and I have a new worksheet with the results:

Widget Report after running macro

Widget Report after running macro

TemplateKicker also has the following features that I will showcase in upcoming blog posts:

  • Nested ForEach loops
  • Rows to insert between items being looped over
  • Generation of named ranges for use in formulas

Even with all this, however, TemplateKicker does have some limitations:

  • The template language is somewhat “fragile”—spaces must be exactly placed.
  • Errors are not reported. Bad syntax or variable names produce undefined results.

Still, I think this is a great start to doing some pretty awesome things in Excel VBA. I do not know if I will develop it further, but if you find it interesting please let me know!

As a side note, CosineWave Technologies Inc. now also offers VBA solutions for business automation now. 😉 Please drop me a line if you have need for some tools to automate your workflow when using Microsoft products (or many other products for that matter)!