Who would say such a thing? Obviously we can’t let that stand. It’s time to bust some myths while raising our own game to the next level.
(An earlier version was published in php|architect, April 2009)
Aside from the trolls who frequent forums and blogs, it’s mainly the enterprise community which carries the lingering perception, rightly or wrongly, that PHP security sucks. As PHP continues to evolve toward the enterprise, it’s going through a slow and messy collision with enterprise culture, standards and criticism. Naturally, PHP and the community have been absorbing lessons and improving, though one of the least understood aspects of this is security and security perceptions. I hope that by discussing security, PHP’s progress can be made smoother and easier than otherwise.
In my simplest definition, security is keeping bad events to a minimum despite even skillful attempts to cause them. If application development is about making an app do what it’s supposed to do, then application security is about making sure an app doesn’t do what it’s not supposed to do – in an environment where hackers and bots constantly scan and probe for weaknesses.
By “enterprise” I mean simply an organization where the stakes are high because of some combination of size, money, purpose and impact. Since a bad event could have severe consequences, there is a corresponding emphasis on risk controls, best practices and rigorous processes, limited by the quality of management.
I’m sure many of you have run into a certain scornful reaction when an “enterprise software developer” talks about PHP that might have gone something like this: “I had to convert this awful legacy code to Java. Whoever wrote it couldn’t program their way out of a paper bag. That’s how I learned PHP. I hope I never see that abomination of a language again.”
The less common “IT security professional” often has a stronger opinion: “PHP is so full of security holes it’s an automatic red flag as far as I’m concerned. Blows my mind that people actually use it – they’re just asking to get hacked.” I’m not just making this up – many of my acquaintances in the IT security community expressed dismay and barely concealed disgust after I told them I chose PHP as my primary development language.
You can almost hear the unspoken thoughts: “A real programmer would use a real language like ______.” I can’t help but believe that these perceptions must be slowing the adoption of PHP. But we don’t have to just sit and take it. We can explain why negative perceptions of PHP are largely the result of distortions of fact and logic.
PHP’s Bad Rap
Possibly the greatest success of PHP has been its accessibility to casual users. Because PHP was designed to be easy to learn and easy to work with, it has attracted hordes of programming novices and tinkerers. Most casual users are simply trying to make things work on the Web and have little desire to learn about programming for its own sake.
My best friend fits this description. He has probably spent hundreds of hours messing with PHP-based software for blogs, forums, events and marketing. But every time I offered to loan him a PHP book he clearly wasn’t interested. Better to work things out the hard way than to pick up a skill he’d rather not have to admit in public. He openly jokes with tech people that he’s a “PHP cutter-paster”.
Unfortunately many people like my friend are generally oblivious about security and couldn’t care less anyway. This creates an easy target and a lazy perception that the “typical” PHP programmer is part of the unwashed masses and makes horrendously clueless mistakes with security. This perception misleadingly conflates programmers with users. The “typical” PHP user isn’t really a programmer and wouldn’t be asked to build applications for the enterprise market – at least I hope not!
I’d guess that a relatively small percentage of all PHP users earn their living developing with PHP, have a solid understanding of modern programming concepts and software engineering practices, and care about the craft of software development. That small percentage group is more likely to be reading php|architect, participating in PHP groups and conferences, and contributing in some way to the PHP ecosystem. To be fair and accurate, these are the true PHP programmers whose reputation for security competency should matter in the enterprise market.
Security vulnerability lists have also helped to distort perceptions of PHP. The PHP core has had a long history of publicized security vulnerabilities which have since been fixed. This is no different from other major software platforms. However, because of the way security vulnerability reports have historically been written (for example as announcements on the high-profile security mailing list, Bugtraq), a long list of additional security problems outside the core have generated “PHP security sucks” headlines simply because they happened to involve some buggy PHP code. I’m talking about well-known forum, CMS and blogging software with their respective ecosystems of modules, plugins etc. – names withheld to protect the guilty. And I’m talking about anything else that gets reported as a vulnerability in random_filename.php.
Just imagine if the C family of languages were treated in the same way, meaning that many Oracle and Windows vulnerabilities would be lumped together as “C vulnerabilities”. With PHP’s taxonomic handicap, a dedicated IT security professional who monitors security vulnerability reports would surely notice the elevated frequency of PHP-related security issues and could understandably – though unfairly – form an unfavorable opinion of PHP.
Another cause of distorted perceptions is that most websites powered by PHP really don’t need industrial-strength security. If a typical blog gets hacked, it’s probably not going to result in a tremendous amount of harm. Restore it from backup, patch it up, and it’s back to normal, more or less. Occasionally the damage is more serious, like when the hacker injects a malware payload that then gets delivered to readers. That would be somewhat of a problem for a site with five readers, but if millions of sites were to be affected it would be disastrous.
Because such a problem would be widely dispersed, it still doesn’t justify a distinct “enterprise security management program” for every site, each with an in-house security guru and a battery of external security audits. So having made the point that most of the PHP world doesn’t need enterprise-class security, the unfortunate side effect is that most of the PHP world is only barely familiar with security. In terms of perception, people tend to take insufficient statistical samples and erroneously extrapolate the “trend”.
No matter how many arguments the community comes up with to defend PHP, I think they’ll have little impact on the opinions of people who already believe that PHP security is substandard. I think we need to go well beyond a defensive posture to move the bubble significantly toward greater acceptance. We PHP programmers who want to build enterprise applications should stretch a little beyond our comfort zone to prepare for what that entails, and then we must step through the door.
What’s Different in the Enterprise
The enterprise is a distinct game that must be personally experienced to be truly understood. Aside from the vapid management-ese and empty buzzword-talk associated with many things “enterprise”, there are real reasons why the security game is different. Enterprise customers have certain expectations, rules, and procedures in place for selecting and acquiring software, especially custom software.
For example, most publicly traded companies are required to have a formal security policy. In the United States, public companies must comply with the Sarbanes-Oxley Act (SOX) and financial services companies have to comply with the Gramm-Leach-Bliley Act (GLBA); both have provisions that mandate information security process and controls. Companies that accept credit card payments must do so in a way that complies with the Payment Card Industry Data Security Standard (PCI DSS). Government organizations typically have a long list of laws and other rules mandating security policy and standards. It’s not uncommon for an IT shop to have literally thousands of rules to follow and to demonstrate to the satisfaction of auditors.
On the brighter side, PHP has been evolving on a trajectory that steadily brings it closer to and deeper into the enterprise market. PHP 5 and the SPL (Standard PHP Library) brought OOP features much more in line with expectations. Frameworks such as the Zend Framework codify modern architectures and practices for re-use. The Eclipse IDE dominates the Java world, so PHP integration via Zend Studio for Eclipse, PHP Development Tools (PDT), and PHPEclipse make PHP a little less alien to Java developers. Others include: Zend Executable Debugger and Xdebug for integrated debugging; PHPUnit and SimpleTest for unit testing; Phing for automating the build process; and PHPUnderControl for continuous integration.
All of these fit into enterprise-class development styles and processes, and they are enablers for robust quality and security practices. But based on conversations I’ve had with members of the enterprise community, the single biggest perceived weakness in PHP is still security. Perhaps this is because enterprise-class security practices are primarily in the human realm and cannot be implemented as a tool per se. Yet those security practices must be reflected throughout the PHP community and ecosystem.
PHP Security Trends
Having said that, there are a number of PHP changes with clearly positive impacts on security. PHP core support for internationalization has been improving, first with a family of functions that support multibyte character encoding, and native encoding support is planned for PHP 6. This will help close the door on a whole class of attacks that get around weak security filters by playing tricks with character encoding. Language features and defaults that previously caused security problems (e.g. magic_quotes_gpc, register_globals) have been removed or deprecated.
Progress, meaning in this case adoption of the previously mentioned advances by the PHP community, has been uneven however. For example, the official end-of-life of PHP 4 in August 2008 had a barely noticeable effect on usage relative to the existing trend. In the enterprise space, continued support is usually an absolute requirement for adoption. In many security policies, an unsupported version is in and of itself a critical “showstopper” security vulnerability that demands immediate upgrade or shutdown of the offending application.
Aside from the enterprise community, other powerful reasons exist for raising the level of PHP security. The threat environment has rapidly evolved; the “black hat” community of hackers and spammers has greatly expanded as they have discovered how to make money from identity theft, spam and other malicious behavior. Hackers now control vast armies of compromised computers via “bots” that automatically scan and compromise additional machines. This evolution increases the likelihood that any given web application will be found, probed and hacked.
Many security vulnerabilities are created in the heat of development when a programmer has a goal of building certain functionality into an application and writes some code to implement that. The problem is that the programmer’s mindset is often focused exclusively on getting that code to work as expected and out the door. For most people it would be an enormous context switch to view the fresh code with a hacker’s mindset and to think of all the possibilities for abuse. The developer may think of some basic security measures, remembering for example Chris Shiflett’s exhortations to “filter input, escape output”, but sometimes a nuance or “abuse case” is missed, resulting in a broken or incomplete implementation of those security measures.
At increasing levels of skill and experience, a common security strategy that I’ve observed among PHP developers boils down to: “Don’t make a dumb mistake that falls into one of the top N types of well known security vulnerabilities. Learn and apply defensive coding practices to anticipate and block potential holes.” This isn’t too bad an approach for a low-risk application such as a blog or a small business website. It’s already a more thorough approach to security than a casual PHP user is likely to implement, but the enterprise community demands more robust security methodologies with which the vast majority of PHP developers probably are not familiar.
Toward the Enterprise
What distinguishes applications that require enterprise-grade security is that there is some reason why such a level of rigor is needed. Otherwise, why would a non-technical executive be willing to spend the money and human energy on security? Enterprise-grade security is designed to handle medium- and high-risk applications, with some combination of high traffic, high visibility, high financial value or sensitive nature. Those factors often trigger security-related laws, regulations, and internally-generated risk controls, requiring a formally documented security policy and often specific practices and standards such as COBIT (Control Objectives for Information and related Technology) and ISO/IEC 27002 (formerly 17799). Standards translate into requirements, which are addressed during architecture and design, and which are then traced via formal documentation, testing, and audits.
What the enterprise methodologies tend to share at the core is a set of fundamental security questions, such as: What data or functionality is sensitive or otherwise important enough to warrant protection? What roles and responsibilities apply? What are the threats that must be addressed? What security controls will provide sufficient protection against the threats? How will the controls be designed and incorporated into the application? How will the controls be validated and tested to demonstrate that they actually provide the intended effect? How will the overall risk level be measured and managed over time?
Understanding those concepts and following their implications will strengthen security in the long term. A good place to start is the Open Web Application Security Project, which has strong support in the enterprise security community. To improve PHP security in the near term, we can and should look for opportunities to apply security tweaks. We should look at PHP use cases associated with frequently created security vulnerabilities to find ways to make it easier for both professional and casual users to do the right things security-wise.
For example, the most straightforward way for a casual user to query a database is by passing SQL, often with dynamic values, directly to a MySQL server with the procedural mysqli_query() or mysql_query(). Safer methods such as mysqli_real_escape_string(), mysqli_prepare(), PDO::prepare(), or even the Zend Framework’s Zend_Db component all require extra steps, extra setup, or extra learning to use properly, so a casual user may not be aware of or inclined to try those without a nudge. Maybe it would help to have a note or warning in the manual entries for mysqli_query() and mysql_query() pointing out the risk of SQL injection and what to do about it, possibly something like:
Warning: Because this function accepts a raw SQL query, there is a risk of a security vulnerability – SQL injection – when that query is dynamically constructed with untrusted input (such as user input). See (http://php.net/security.database.sql-injection). To ensure that a query cannot be altered at runtime by injecting MySQL special characters, always validate, filter and/or apply mysqli_real_escape_string() to untrusted input before using it in the query. Alternatively, consider using mysqli_prepare(), PDO::prepare(), or a library or framework wrapper that has features to protect against SQL injection.
A stronger approach would be to transform the input into canonical standards-compliant form, and to apply a whitelist filter at the level of HTML tags and attributes. That kind of approach is built into the HTML Purifier library.
If we intend for PHP to advance into markets that demand security (i.e. the enterprise segment), then we must match impedance between our capacity to deliver and the expectations of our desired customers. Those of us who want to develop for enterprise organizations must understand and integrate with enterprise security processes, standards and best practices.
We should carry the cultural markers that signal our belonging to the enterprise community, such as fluency with expected concepts, practices, standards and tools. We should convince others through our language, our questions, and most importantly our code that we understand and implement security to the depth, quality and consistency that enterprises demand.
We must show by example that we can scale from having an elite group of proven enterprise-ready programmers to having a broad base of such programmers. PHP projects should be continually improved to reflect increasing levels of security understanding. If we learn, teach, and implement steadily increasing levels of security knowledge and practices, we can overcome the perception that PHP security sucks.