One other small note, while it's at the forefront of my mind. It's November 11th, and just after 11 am. Watching the airport around me stop for the national anthem and two minutes of silence was uplifting. I'd intended to stand on my own, but watching the entire terminal around me stop was... awesome. A word I use in this case in the traditional sense.

My camera spent the entire event in my travel bag. Though I would have loved a shot, the moment itself was worth more than the picture.

Note: This article doesn’t contain anything new or ground breaking. This is the stuff that you should know already because it’s been written about before by people smarter than me. Tragically, despite lots of great material on subject people keep messing it up.



So, cross site request forgeries are a pretty common topic these days; they’re in almost every security talk, book, site etc. This is okay; they’re important (but I wish people would concentrate on security as a whole rather than just worrying about problems with nifty acronyms). Most of the sites, and all of the books I’ve read demonstrate things correctly, but when it comes to actual implementation, time and time again, I see code that’s just wrong. This CSRF Demonstration page will be used throughout this post.

In order to effectively use the common transparent defense against CSRF attacks you need to generate an unpredictable token, and confirm its presence in both the session and form submission upon receipt. Only two essentials there, but I’ve seen lots of live code that fails on at least one of the two.

Comparison

So, the point of CSRF is to confirm that the CSRF token in the session is equal to the one received with the form post. This is critical and easy, though people seem to manage to screw it up. They write code that looks remarkably like this:
if ($_POST['csrf'] == $_SESSION['csrf'])

Do you see the fatal flaw? If both the session and post variable are empty, they’re also equal. So if you’re attacking the form you simply omit the post variable. I demonstrate this attack on my negligence csrf attack page. Not only do you need to ensure they’re equal, you also need to ensure that they’re both set and non-empty.

Note I’ve left the warnings in on purpose. I could have turned off display errors, or suppressed them, but I really wanted to show what was happening.

Unpredictable Token.

This part should also be easy; generate a token that the attack can’t guess. I haven’t actually said random here, though random is good. The important part is that the attacker can’t guess it. I have a piece of information for you that shouldn’t be news, but it might be. Time isn’t random. Time increases by one, once a second, every second. MD5 also isn’t random. Thanks to the snowball effect the hash of very similar values are actually very different, but they are in no way random. Now combining these two non-random values also happens to give you a non-random result. Yet, time and time again I see code exactly like this:
$csrfToken = md5(time());

This is idiotic. Throwing a hash function at the problem doesn’t solve anything. It’s obfuscation, and weak obfuscation at that.

Now I’ve mentioned this at talks before, and the audience has politely nodded, then privately told me that it doesn’t actually matter. It does, so take a look at the md5 time attack page.

Now adding a little bit of salt also doesn’t solve the problem, it’s just more obfuscation.

If you’re interested you can also see the source code for my weak csrf page.


Stefan Esser’s talk at ZendCon Lesser Known Security Problems in PHP discusses a few other issues related to sessions you may want to take a look at.

So please go home and fix your CSRF pages.

(s/messing/&$#@ing)
So this year at php|works we’re trying something a little different for the evening entertainment, You! (we had enough of me at php|tek).

The format is a little bit different than a talk (thank god) and hopefully a lot more fun. Basically the presenter gets up there with twenty slides, each are going to be shown for exactly 20 seconds, for a total of six minutes forty seconds. No take backs, no do-overs, no boring slides full of code.

The format lends itself well to quick, interesting presentations on pretty much anything. Plus, if you give a talk I’ll be buying you a drink!**


A couple of quick FAQ points:
Q: Do I have to be a speaker to give a talk?
A: Oh gosh no! I’ve heard enough of those guys already, I’d love to get some fresh blood up there.

Q: Does it need to be on PHP?
A: Oh gosh no! Make it interesting, make it on something important, something cool, something trendy! Remember there’s Python folks in the crowd as well.

Q: Why should I give a talk?
A: It’s fun. It’s a new format, something interesting to try, plus we have prizes.

Q: I’ve never given a conference talk before, I’m a bit nervous about this whole thing.
A: That’s not actually a question. I’ll speak to your point anyways, this is a great way to get some exposure to decision makers for our conferences and other ones, if you’re good we’ll remember you, next time there’s a CFP we can say “Oh we say her/him at php|works, let’s get em!”. Plus it's fun, and Paul will clap politely no matter what.

Q: Will Paul keep his pants on?
A: Magic 8-Ball says: Unclear.

Q: Will Kiss be making an appearance?
A: Tragically, probably not.


So yeah, send Elizabeth Naramore an email with your interest quickly while there's still a few slots left. She's at elizabeth at phparch dot com.


**While it's still an open bar.
I have a lot of pet peeves, and in order to start blogging more often you might be hearing about them, sorry.

One of them is stupid ways software downloads work, in particular software designed to be run on a server. This umbrella category includes pretty much every PHP application you might download (arguments from Elizabeth Smith not withstanding). Why do all these sites insist on being “helpful” and redirecting my browser to a download link? I don’t want to download the file to my computer, I want the file on a server in another country!

Some sites, dissatisfied with merely making you hit stop, copy the direct download link to clipboard and paste in a terminal window go one step further! They refuse to serve files unless you’ve got a cookie. So just having the right link doesn’t work, I have to boot up lynx, surf to the page, hit the download link again. This is freaking stupid.

Provide real download links for software designed to run on the server, stop requiring cookies to download your software, just make things work.

Example Culprits include PHP itself for the whole redirection business, and Magento for necessitating a cookie.

Hi, I’m Paul Reinheimer, a developer working on the web.

I co-founded WonderProxy which provides access to over 200 proxies around the world to enable testing of geoip sensitive applications. We've since expanded to offer more granular tooling through Where's it Up

My hobbies are cycling, photography, travel, and engaging Allison Moore in intelligent discourse. I frequently write about PHP and other related technologies.

Search