I posted this rather lengthy argument in the Zend fw-core mailing list after I learned that the
Zend_Filter_Input component had been dropped from the Zend Framework. I have used this component extensively in various projects, and had written up a contribution to the Zend DevZone that described using a bootstrap script to block direct access by your developers to the superglobal user input arrays ($_GET, $_POST, $_COOKIE, etc).
I want to be clear that I think the ZFW project leads have done a very good job of guiding the development of the framework. I think they’re very smart, capable folks who have done a ton of good, hard work. I just disagree strongly with what’s happened to the input filtering components, and feel that it should be addressed before the 1.0 release.
Here’s my post:
Let me start off with some context. If we do a search for ‘php’ in the 2006 records of the NIST NVD, over 40% of the total number of vulnerabilities are returned. Removing language level issues, which would account for a small number of these, we’re left with an enormous number of PHP application vulnerabilities — well over 1/3 of all the 2006 entries in the NVD, for sure.
I believe those numbers say a lot about the following things: 1. How popular PHP is 2. How much web applications are a target 3. How many PHP devs are incapable of writing secure applications
I don’t necessarily fault PHP as a language for this, as I think any language of similar ease and popularity would suffer many of the same problems. And as more and more of our business and social activity is conducted online, web applications are inevitably going to increasingly be targeted.
But we can do a lot about #3, in two major areas: education, and empowerment.
Education is fairly easy to understand, I think: books, training courses, articles, tutorials, etc. In a sense, the ZFW project has a significant opportunity to educate PHP developers by serving as an example to the community. Zend’s profile in the community gives it an opportunity to raise the bar, and change expectations about what effective, secure web app development entails.
Empowering developers, in my mind, means making it easier to do the right thing. Our toolsets — editors, debuggers, frameworks, etc — should make it easier to write secure applications. The default action should be the secure action. It shouldn’t be impossible to do potentially dangerous stuff, but it should require clear intent on the part of the developer.
This is where I feel the Zend Framework has regressed as of version 0.8. Out of the box, it is more difficult to write secure applications with ZFW as of 0.8.0 than it was in 0.7.0.
For example, let’s look at stripping tags from user input. In 0.7:require "Zend/Filter.php"; $searchtxt = Zend_Filter::noTags($searchtxt);
In 0.8:require "Zend/Filter/StripTags.php"; $noTags = new Zend_Filter_StripTags(); $searchtxt = $noTags->filter($searchtxt);
Only one extra line, but when you’re having to instantiate a new filter every time you want different functionality, it adds up. And if you’re not using class autoloading, you have to do a require statement for every filter class, whereas in 0.7 you only needed to do a single require.
In some ways, the new Zend_Filter is a win, especially in terms of expandability, but it lacks the proper hooks for making filtering and validation as speedy and easy as it was before. Make no mistake: verbosity matters. I am not alone in preferring an option that makes me type less.
More disturbing, though, is the total removal of the Zend_Filter_Input component from the ZFW. ZFI was a very effective tool for limiting access to user input arrays like $_POST and $_COOKIE, wrapping them in an object and forcing the developer to use object methods to access the data.require "Zend/Filter/Input.php"; $f_POST = new Zend_Filter_Input($_POST); $searchtext = $f_POST->noTags('searchtxt'); $id = $f_POST->getInt('id'); // you can only get the raw input with the getRaw method $unfiltered_input = $f_POST->getRaw('xssWaitingToHappen');
It wasn’t perfect — as of 0.7 it lacked iterative access and didn’t work well with multidimensional arrays — but it established a strong new paradigm for PHP development that was a long time in coming. The vast majority of vulnerabilities in PHP apps come from mishandling user input, and Zend_Filter_Input made it significantly easier to do the right thing, and significantly harder to do the wrong thing. This was a major jewel for the Zend Framework, something no other high-profile PHP framework was offering (AFAIK). And it evidently had been considered a fundamental component, having been present in the core since the initial public release (0.1.2). Now, it’s gone, with no comparable functionality in place, and no concrete plans to restore it.
Zend has a significant opportunity to influence how PHP development is done with the ZFW 1.0 release. The Zend Framework will be, for better or worse, considered an example as to how PHP development should be done. It’s disappointing, then, to see the framework move backwards in terms of easing secure development while it speeds towards 1.0. This opportunity will not come again. I hope these decisions are reconsidered, and the feature freeze is delayed so that previously-existing functionality can be restored.
[tags]zend framework, php, security, infosec, webdev, zfw, input filtering[/tags]