About the Author

Chris Shiflett

Hi, I'm Chris, a web developer and a founding member of Analog. I live and work in Brooklyn, NY.


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.

19 Comments

1. S's GravatarS 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's GravatarS said:

Nice work. (-:

S

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


3. bucky's Gravatarbucky said:

Im gonna guess your hidden field called return_url.

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


4. paul's Gravatarpaul said:

test

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


5. preinheimer's Gravatarpreinheimer 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. <Jaydee>'s Gravatar<Jaydee> said:

ok time to figure out the vulnerability =)

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


7. Mike Willbanks's GravatarMike 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's GravatarChris Shiflett said:

Mike wins. :-)

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


9. preinheimer's Gravatarpreinheimer 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's GravatarChris 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. preinheimer's Gravatarpreinheimer said:

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

Point 9

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


12. Chris Shiflett's GravatarChris 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's GravatarJayde 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's GravatarChris 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's GravatarSencer 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's GravatarFlavio 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's GravatarFlavio 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's GravatarChris 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's GravatarFlavio 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


Post A Comment

Personal Details and Comment

Style Guide

Line breaks are converted to paragraphs. Also use:

  • <a href="" title="">text</a>1
  • <em>text</em>
  • <blockquote><p>text</p></blockquote>
  • <code>2  <?php  if ($foo) {      $foo = TRUE;  }  ?></code>
  1. Note: <code> can be used inline (e.g. in paragraphs) or in a block as shown. Include whitespace and newlines in blocks.

Please enter Chris (my first name) below. This is a primitive spam prevention technique, and I apologize for the inconvenience.

Preview and Submit

Upcoming Talks

ConFoo

10 - 12 Mar 2010

At Hilton Montréal Bonaventure, Montréal, Canada.

South by Southwest

12 - 16 Mar 2010

At Austin Convention Center, Austin, Texas.

Dutch PHP Conference

10 - 12 Jun 2010

At TBD, Amsterdam, Netherlands.

O'Reilly Open Source Convention

19 - 23 Jul 2010

At Oregon Convention Center, Portland, Oregon.

New Comments

Chris Shiflett wrote:

Glad it helped, Niall!

Posted in Git on Snow Leopard
Niall Kelly wrote:

Having tried other methods without success and looked through plenty of bloated documentation, th...

Posted in Git on Snow Leopard
liukang wrote:

I have problem with this example. In my php.ini magic_quotes_gpc is off so i'm using only addsla...

Posted in addslashes() Versus mysql_real_escape_string()
RyanTheGreat wrote:

Well, I'm not Chris, but I will do my best to address the questions raised in the comments by Ian...

Posted in Security Corner: Cross-Site Request Forgeries
Chris Shiflett wrote:

Thanks for the kind words, Simon. I'm glad you liked the tutorial. In case it's helpful, here'...

Posted in Webstock

Browse Comments


Work and Books

Analog Essential PHP Security HTTP Developer's Handbook