A question that seems to come up pretty frequently on various PHP mailing lists is how to convert "smart quotes" to real quotes. Dan Convissor provided a simple example that performs such a conversion a year or two ago on the NYPHP mailing list. I've modified it slightly to fit my own style preferences:
$search = array(chr(145),
$replace = array("'",
return str_replace($search, $replace, $string);
(This function also converts an emdash into a hyphen.)
If you want "smart quotes" to actually appear in a browser, you can use the following $replace array to convert each of these characters into HTML entities:
$replace = array('‘',
These entities render properly in most browsers I've tried, including lynx. Here's some example HTML:
Here is how these entities render in your browser:
The htmlentities() man page has other useful examples in the user notes at the bottom, some of which convert a wide variety of characters into valid HTML entities.
As has been widely discussed, Zend announced its PHP Framework this week. I wasn't invited to participate, so I think I can offer an unbiased opinion. The primary misconception seems to be that there is no code, and this isn't true. Although Zend thinks the framework is too immature to be released yet, it does exist. There are also some very smart people contributing to the project, and it's not just big companies like IBM - guys like George and Wez are also helping out. I'm giving it the benefit of the doubt, and I have high hopes for this project.
I'm particularly interested to see whether this effort capitalizes on the chance to help PHP developers write more secure code. In addition to support for filtering input (which I'm told is included), here are some characteristics I'm hoping to see:
- Something comparable to a taint mode. Developers need to be able to easily and reliably determine whether a particular variable is tainted. The framework can keep up with this and offer a simple inspection mechanism. Currently, developers must rely on discipline, and it's easy to make a mistake.
- An intuitive way to escape output. When someone wants to escape data to be used in a URL that is also the target of a link, it needs to be passed through urlencode() and then htmlentities(). The nature of representing data in different contexts is confusing for many developers, and I think the framework can help.
- Protection against session fixation. For example, if I use something native to the framework to modify a user's privilege level (so it knows what I'm doing), I want the session identifier to be regenerated automatically. Of course, this behavior could be optional.
- Protection against session hijacking. There's a lot that can be done here. Even Defense in Depth measures such as propagating an auth token would be nice.
- CSRF protection. The framework could even make this transparent, so that a token is added to all HTML forms, and this is checked upon submission. If this check fails, let the developer decide what to do (if anything) - maybe just throw an exception. This type of approach can offer an easy solution for security-conscious developers without eliminating the flexibility that we've all come to expect and appreciate about PHP.
- Support for persistent logins. Many developers want to add a "remember me" feature, and poor implementations of this are the cause of many security vulnerabilities.
- Simple and secure authentication and authorization mechanisms. These are features that almost all PHP applications need, and OWASP lists both broken authentication and broken access control (authorization) on its top ten list of critical web application security vulnerabilities.
These are just a few of the things I'd like to see. What's on your wishlist?
The first annual ZendCon has now come and gone. Prior to the conference, I had my doubts about an open source conference with a big business twist, but Zend and KB Conferences pulled it off. For the first time, the average conference attendee could see how seriously big businesses (IBM, Yahoo, Oracle, eBay, Google, etc.) are taking PHP. The conference also seemed to generate a lot of buzz in the business community with a sense that PHP is a serious threat to Java's future in the web space.
The fourth and last day of the conference began very early for me, because I had the misfortune of speaking at 8:30 AM. Luckily, quite a few attendees were anticipating the talk, so I still had a good crowd. (Hopefully I wasn't too tired to deliver it well.) The talk, PHP Security Audit HOWTO, described the basics of auditing PHP code with a focus on tracking data. I only had 45 minutes to speak, so it's hard to cover much more. My desire is to encourage more peer review within the PHP community, because this is a practice that offers a lot of value and is something almost any development team can do. Although the slides only offer an overview of the actual talk, you might find them useful:
Note: Keynote's Flash export of this talk is rubbish, so I'm only offering a PDF for now. Sorry.
Like Adam, I was filmed for some sort of promotional video. It wasn't scripted or rehearsed in any way, so I'm afraid to see the results. Luckily, it will be edited, so maybe they can salvage something. :-)
As always, it was good to see old friends, make some new ones, and learn something in the process. I think ZendCon was a big success, and I look forward to next year's conference in San Jose.
I have quite a few photos of the conference available in my ZendCon gallery.
As expected, I wasn't able to keep up with blogging during the conference very well. I do want to mention Michael Radwin's talk, PHP at Yahoo. It was a nice mixture of business and technical content, and there were some key points that I wanted to note:
- Yahoo gets some obscene traffic - 411,000,000 unique visitors per month, 191,000,000 active registered users, 11,400,000 paying customers, and a boggling 3,400,000,000 page views per day.
- Yahoo organizes code into four categories - HTML templates (95% HTML, 5% PHP), template helpers (50% HTML, 50% PHP), business logic (100% PHP), and core code written in C and C++.
- Yahoo uses a very basic mod_php and loads extensions as necessary with php.ini.
- For security, they use open_basedir, disable allow_url_fopen, and use the input_filter hook.
Michael made some interesting points regarding security. For example, they use libcurl rather than enable allow_url_fopen, because (among other things) this makes auditing code easier - you have something to search for. For a similar reason, they use the input_filter hook, but they also provide developers with ways to access raw data - this also gives them something to search for during audits. I think this general approach has a lot of merit, particularly for companies with very large development teams (Yahoo employs several hundred PHP developers).
I'll fill in a few gaps and post a conference summary over the weekend. The short summary is that it was a very successful conference - organized, well-attended, and valuable.
I missed Andi and Zeev's keynote this morning but got to see Rod Smith from IBM speaking about Web 2.0. Well, that was the title of his talk, but I'm not sure what was Web 2.0 about it. What I found interesting about Rod's talk was that he made the enterprise seem more enlightened than you might think. For example, when he talked about the tendency to add unnecessary complexity, he offered some reasonable explanations. Enterprise companies know complexity is bad, and they're trying to learn from the PHP community. We tend to get the job done in a more direct and pragmatic manner, and that approach has a lot of value. This is one of the many reasons behind IBM's interest in PHP.
I sat in on a few minutes of Neil Green's talk about PHP frameworks. His talk focused on characteristics of an enterprise PHP framework, and he offered some pretty solid opinions. I particularly liked that he stressed the importance of considering security as part of the design. (I'll speak about this framework later.)
At lunch, I ran into the NYPHP crew. There are 5 of us here (6 if you count Adam), which is a pretty good showing for a user group from the opposite coast.
After lunch, Marc spoke about "2005, a Web Odyssey." His talk was almost two different talks - the prepared content and the Q&A period. He spoke about trends in the industry and focused on the transition from languages written for machines to languages written for developers. He thinks Java marked the beginning of this transition and that PHP is now in the spotlight. When speaking about PHP's dominance in the web space, he pointed out that more web applications will be written in the next five years than have been written to date. Thus, those technologies that dominate in the next five years will win, and PHP looks poised to do just that. The Q&A period allowed Marc to showcase his personality a bit more as well as touch on just about every corner of the software industry.
I also sat in on most of Wez's PDO talk. I've seen parts of this before, so most of it was familiar. Wez does a particularly good job of highlighting core PDO features with small, focused code samples and clear explanations.
I briefly stopped by the exhibit hall (and PHP 10th anniversary party) before heading to the Ning party at Marc's house. I met a few people (like Diego) whom I had only worked with via phone and email. Marc has a nice place, and there was some good food and conversation.
Michael will be speaking about PHP at Yahoo tomorrow, and I'm interested in seeing that. There are also talks from NASA, Intel, eBay, and SAP, so it looks like a very business-oriented day for ZendCon.
I'm attending the Zend PHP Conference and Expo (which I've decided to call ZendCon for convenience) this week. The conference is taking place at the Hyatt Regency in San Francisco (Burlingame if you're picky). The venue is very nice, and the business focus is proving to be more interesting than I expected.
Yesterday was the first day of the conference, but it was just tutorials, so it lacked the attendance, keynotes, and other stuff that accompanies the "real" conference days.
I gave a tutorial called Securing PHP Applications that I think went really well. The night before, I decided to cut out some material to make room for a case study of the Myspace worm. I think most people appreciated seeing a real-world scenario that solidified many of the topics I was discussing in the talk. I also think there is quite a bit of confusion and misunderstanding about the mechanics of the worm (specifically about the role XSS played). I plan to collect some of my notes and blog more details about that.
Most people seem particularly interested in the fact that AJAX was used to subvert the CSRF protection that Myspace employed. Someone reminded me that I described this scenario in a comment I made a month or two ago. It was also a scenario that I researched in a recent consulting engagement.
I plan to cover the conference pretty well in my blog, so stay tuned. :-)
I just received my copy of Essential PHP Security, which means it should be on shelves within a few days. I'm very happy with it, especially the size. Apple's iPod nano isn't the only thing that's impossibly small. :-)
A sample chapter will be available soon from MySQL's Developer Zone, and another chapter is already available from O'Reilly:
I hope you enjoy it. Please buy a copy. :-)
In the comments to my article on CSRF, someone questioned whether CSRF is really anything worth worrying about. Rather than give a hypothetical example, I can point to a real one that is getting some attention today:
This attack seems pretty harmless (I'd rather not discuss ethical concerns), but it demonstrates something very powerful - a combination of XSS and CSRF. If your site has XSS vulnerabilities, they can be used to launch much more effective CSRF attacks. Rather than only a small percentage of people being affected, everyone is, because the attacker is guaranteed that all victims have an established relationship with the target site, yours.
More information about XSS and CSRF can be found here:
PHP Quebec's call for speakers is now open:
PHP Quebec 2006 will take place in Montreal, Quebec, Canada, at the Plaza Montreal Hotel. The conference will take place between March 29th and 31st 2006.
If you attended this conference last year, you know how awesome it was. If you missed it, I think Toby has some photos. :-)
The 2006 conference will have three tracks:
- Professional Development, with tools related to software development. The track is open to revision control tools, analysis and design tools, communication, and others.
- PHP Advanced Techniques, covering in-depth details of PHP techniques.
- Databases, covering databases that can be used with PHP and their related tools.
Submit your proposals before Fri, 04 Nov 2005.
Slashdot is running a story about Linux IM clients. The article to which the story refers claims that the lack of a good IM client is hurting Linux as much as anything else. I find this surprising, since Gaim seems better than any IM client I've used (I've tried most native clients, Trillian, and Adium). Trillian is just plain fugly and unusable and most native clients have ads and only connect to one network (which makes them useless to me). To be fair, Adium isn't bad, but it could be better. Am I missing something?
More surprising is that the author (who resides in Belgium) seems to think that MSN dominates:
Young people in European countries just can't live without MSN.
I'm curious to know whether others agree with this. Based on my "buddy list" (which is pretty big), Yahoo is the only IM network competing with AIM in terms of popularity. The only MSN people I have are Andi and Zeev. I have more Google Talk contacts than that.
Congratulations are due to Marcus Whitney and Chris Cornutt of the Pro-PHP Podcast for making the iTunes Top 100 Podcasts:
Pro-PHP is also currently listed on the front page of Podcasts in the iTunes Music Store:
Marcus and I are scheduled to record another Ask Chris this week. If you've got any PHP questions you'd like to see answered, just leave a comment.
A recent comment by Jeremy Chin (replying to my article The Truth about Sessions) likens my writing to teaching a man to fish:
Give a man a fish and he'll eat for a day. Teach a man how to fish and he'll eat for a lifetime. I definitely think your article belongs in the latter as you did a marvelous job of explaining the mechanics of how servers handle requests, and how security holes can be, and are, exploited.
I want to thank Jeremy for his kind words, and I also want to highlight the reasoning behind my writing style and why I am particularly happy to see someone make this analogy.
Web application security is a young and evolving discipline. There are very few "right answers" in this field, and many security professionals are hesitant to offer advice for fear of being misunderstood or wrong. If a safeguard is misapplied or offers insufficient protection, the author's reputation is at stake.
I enjoy my role in the community largely because I'm not too concerned with reputation. I believe that by genuinely trying to help people, a certain amount of forgiveness is afforded. However, I take my role very seriously, and I think it's important to offer sound advice, particularly regarding security. This is why my writing style is to explain a problem as thoroughly as possible before offering a solution. By explaining the reasoning behind a particular solution, I think readers can better understand and appreciate the protection it offers. In addition, there are many smart people in the PHP community, and the more people who understand a particular problem, the better the solution(s). (I'd love to see a really good non-SSL solution to session hijacking.)
This is why readers can comment on any of my articles. If you think you spot an error or want to share a particularly creative solution to the problem being discussed, just leave a comment. I read them all, and I plan to keep all of my articles updated.
I'm still trying to catch up on posting articles to my web site - there are now four more available for free:
If you only read one, read the article on CSRF (cross-site request forgeries). I think it is one of the most overlooked attack vectors around, and it doesn't receive the attention it deserves. If you've never heard of CSRF, I bet your applications are vulnerable.
Note: If you're interested in CSRF attacks, you might want to view the slides of PHP Security by Example (with class files) and follow along with the exercises - one of them covers CSRF, so you can try it out for yourself.
Earlier this year, I received an email from Marc Andreessen inquiring about some PHP security consulting. Being well aware of Marc's role in Internet history, I was curious to learn about his new project and eager to help out.
Others were also curious, but not in a very supportive way. Mark Fletcher had this to say about Marc's company:
Who knows what they do, but whatever it is, they're doing it wrong.
Well, now you can judge for yourself - Ning lives!
Ning is an attempt to lower the barrier of entry for creating social applications. The idea is that there are plenty of great ideas out there for these things, but the barrier of entry prevents many of them from coming to fruition. It's also a hassle for users of social applications to have to create a different account for every one.
One interesting thing about Ning (aside from the fact that PHP plays such a major role) is that it is open source in nature - you can clone any Ning application (some exist specifically for this purpose) and "mix" it to suit your needs. Ning describes this as "clone, mix, and run."
It will be interesting to see what sort of applications this yields.
On a different note, I was also happy to hear that my book went to print yesterday. The two biggest reasons why I've had no time these past few months are finally finished. Now I can sleep. :-)
If you're picky about the format of your HTML like me, you've most likely noticed that PHP strips newlines that exist immediately after a closing PHP tag. Try the following code:
<?php echo 'TEST'; ?>
You might be surprised to see that this outputs the following:
As PHP developers, most of us expect that anything not within a PHP block is left alone. After all, that's supposed to be the point of the opening and closing PHP tags. (This is the only exception of which I'm aware.) The expected output is as follows:
This has been mentioned on the NYPHP mailing list, but I don't remember seeing it discussed anywhere else, and no one could come up with a good reason for the behavior.
There is an explanation offered here in the manual:
Why does PHP do this? Because when formatting normal HTML, this usually makes your life easier because you don't want that newline, but you'd have to create extremely long lines or otherwise make the raw page source unreadable to achieve that effect.
If you're like me, you're probably a bit surprised to see that this annoying behavior is supposedly there to "make your life easier." I can't think of a situation where I would want this behavior. Am I missing something obvious?
There seems to be a growing amount of interest within the PHP community about the slow rate of PHP 5's adoption. Call me crazy, but I tend to think of this as a testament of PHP's success, because it might mean:
- PHP 4 suits many people's needs, so there's no pressing reason for them to upgrade (think about Apache 1.3).
- PHP is being used in environments where upgrading is a very controlled process (Yahoo, for example).
I also think PHP 5 will reach a tipping point (check out the book) eventually, so the early rate of adoption isn't necessarily a forecast of PHP 5's future.
Speaking of PHP 5, Upgrading to PHP 5 is one of my favorite PHP books. Despite being a technical reviewer for the book, I find myself referencing it more than any other. Adam does a great job of explaining the new features in PHP 5, and the chapter on OOP is especially good.