About the Author

Chris Shiflett

Hi, I’m Chris, a web craftsman making things like Mapalong & Brooklyn Beta with my friends at Analog.


php|architect: March 2006 Edition

Another edition of php|architect has been published. I was especially excited to read this one, because it's Ilia's first month writing Security Corner. It's nice to see a topic explained from a different point of view, and there is still too little interest in security within the PHP community. (In other words, this is a rare opportunity.)

He discusses cross-site request forgeries, an attack first mentioned in php|architect back in 2003. Sadly, it remains one of the most dangerous, yet relatively unknown attacks. It deserves more attention.

I was a bit concerned that Ilia might liken it to cross-site scripting (XSS), because he has in the past:

As far as CSRF, I don't really consider it to be separate from XSS [...] CSRF is a subset of cross site scripting in my opinion.

(I didn't debate this point at the time, because the Myspace worm had caused a fair amount of confusion by combining both attacks, an approach I had been researching). My concern was quickly put to rest:

Closer examination reveals that CSRF and XSS are entirely different beasts.

There are still a few minor points where Ilia and I seem to disagree, but that's the real beauty of having different points of view. Hopefully Ilia will forgive me for it. :-) My points of contention are:

  • There are many different attack vectors for CSRF - it's best to find the commonality between them, so you can eliminate the root cause of the problem. Focusing on one attack vector can yield weak solutions.
  • An attack can be launched from any web site, so preventing your own site from being a platform for CSRF does not protect you from the attack itself.

In order to explain these items further, I want to share a secret with you. The comment form on my blog is vulnerable to CSRF. No images are allowed, and no XSS vulnerability exists (to my knowledge), but it's still vulnerable. This was a design decision I made when I first decided to allow comments, because:

  • I already allow anonymous comments, so there's nothing to gain by forging a request from someone else. In other words, I'm not putting readers at risk.
  • I was curious to see whether CSRF's lack of popularity applies to exploits as well as vulnerabilities.

Surprisingly, no one has exploited the vulnerability, despite the fact that there have been a countless number of XSS attempts. That may all change now that I've mentioned it, but when it does, I'll implement a simple and effective safeguard. Can you guess what it is?

About this post

php|architect: March 2006 Edition was posted on Mon, 20 Mar 2006 at 19:47:07 GMT. Follow me on Twitter.

19 comments

1.S said:

Well, it depends on what you consider CSRF, I guess.

Here's my guess:

reallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetextreallywidetext

(but that's pretty weak)

S

Mon, 20 Mar 2006 at 22:23:16 GMT Link


2.S said:

Nice work. (-:

S

Mon, 20 Mar 2006 at 22:23:35 GMT Link


3.bucky said:

Im gonna guess your hidden field called return_url.

Mon, 20 Mar 2006 at 22:52:21 GMT Link


4.paul said:

test

Tue, 21 Mar 2006 at 00:40:59 GMT Link


5.Paul Reinheimer said:

This would be much easier if Opera & FireFox didn't block attempts to use XMLHttpRequest Open like that:

Error: uncaught exception: Permission denied to call method XMLHttpRequest.open

Inline script thread

Error:

name: Error

message: Security violation

Tue, 21 Mar 2006 at 00:52:12 GMT Link


6. said:

ok time to figure out the vulnerability =)

Tue, 21 Mar 2006 at 08:19:54 GMT Link


7.Mike Willbanks said:

My guess would be that you would simply add a token field to the form to make sure that the form is actually being submitted by the actual form. Simple yet effective technique that doesn't seem to be used in much open source software.

Tue, 21 Mar 2006 at 14:07:45 GMT Link


8.Chris Shiflett said:

Mike wins. :-)

Tue, 21 Mar 2006 at 15:03:07 GMT Link


9.Paul Reinheimer said:

While the token is an excellent method, it isn't fool proof. IIRC the myspace worm first retreived a page to locate and store the token, then sent it back with the data it was attempting to propegate.

Tue, 21 Mar 2006 at 16:28:00 GMT Link


10.Chris Shiflett said:

If the token was inadequate, Myspace would have had to do more than fix their XSS vulnerability.

Tue, 21 Mar 2006 at 16:32:26 GMT Link


11.Paul Reinheimer said:

http://namb.la/popular/tech.html

Point 9

Tue, 21 Mar 2006 at 23:27:12 GMT Link


12.Chris Shiflett said:

You're still missing the point. :-)

XMLHttpRequest is bound by the domain sandbox. The only reason he was able to use it against Myspace, is because their XSS vulnerability let him inject his JavaScript into their domain.

If you don't believe me, try his exploit now that they've corrected the XSS vulnerability.

Tue, 21 Mar 2006 at 23:31:58 GMT Link


13.Jayde said:

Oh ok now I get the point where the comments form is susceptible to CSRF from sites vulnerable to XSS =) So this is a sample "chaining" scenario you mentioned in your security tests.

Wed, 22 Mar 2006 at 01:05:27 GMT Link


14.Chris Shiflett said:

Jayde, yes, the "chaining" I was talking about is the same technique used in the Myspace worm. But, just to be clear, Samy didn't learn that from me. He independently discovered it.

Also, without XSS vulnerabilities, you can still be vulnerable to CSRF. This comment form is an example. (It is still vulnerable, by the way.)

Wed, 22 Mar 2006 at 04:55:35 GMT Link


15.Sencer said:

Textpattern has been using nonces in comment-forms for ages. Not only does it prevent CSRF, but it also reduces Spam considerably if paired with an additional forced preview (at least in today's landscape).

Wed, 22 Mar 2006 at 07:55:09 GMT Link


16.Flavio daCosta said:

Just testing...CSRF [this form was blindly submitted via http://n0p.net/chris ]

Seems like the name should be Cross Site Request Coercion as the request is authentic, its only the intention which is forged.

Tue, 18 Apr 2006 at 06:00:44 GMT Link


17.Flavio daCosta said:

Just testing...CSRF [this form was blindly submitted via http://n0p.net/chris ]

Seems like the name should be Cross Site Request Coercion as the request is authentic, its only the intention which is forged.

Tue, 18 Apr 2006 at 13:00:47 GMT Link


18.Chris Shiflett said:

Sencer, that's my preferred technique, but there are other approaches. For those wondering what a nonce is, another common (and more descriptive) term is one-time token (OTT).

As far as spam goes, I also noticed a decrease in comment spam when using a token, but I noticed a much more dramatic reduction when I added the "Chris's First Name" stuff.

Flavio, I assume you figured out how to exploit my form. Well done. :-)

Regarding the name, I can certainly see your point. However, I think coercion implies that the victim has a choice, which is not the case. I think the name is much more accurate and descriptive than XSS, which is misleading. Either way, the one thing we need more than anything is consistency, so I plan to continue to use CSRF.

Mon, 24 Apr 2006 at 04:28:11 GMT Link


19.Flavio daCosta said:

I totally agree on the consistent naming scheme. I guess it came out wrong in my comment as I wasn't actually implying that it should be changed, I was just trying to be a little though provoking I suppose :-P

Thanks

Flavio

Mon, 24 Apr 2006 at 13:11:28 GMT Link


Hello! What’s your name?

Want to comment? Please connect with Twitter to join the discussion.


Work and Books

Analog Essential PHP Security HTTP Developer's Handbook