PHP Application Insecurity - PHP or Devs Fault? 200
somersault asks: "There have recently been a lot of people making jokes at the expense of PHP, but how many common security flaws in PHP are the fault of the language, and how many the fault of the developer? A recent Security Focus article (via the Register) has a brief discussion which suggests that PHP is no less secure than any other scripting language, and that it is the users of the language themselves who need to be educated. The other side of the story is that the developers of PHP should work on tightening up the language to make it more 'idiot proof' by default. Should the team developing PHP take a more active role in controlling the use of their language? What will it take to ensure that users of the language learn to use it securely, short of defacing every vulnerable website out there?"
what's the purpose of a language, anyway? (Score:3, Informative)
I mean, why can't we all just write our code in assembly language and get it over with?
The fact of the matter is, that a programming language is a productivity tool. It is supposed to enable the programmer to more simply express complex actions rather than having to deal with all of the low-level particulars.
PHP advertises itself thus:
So, should the language be "idiot proof"? No, not necessarily, but it should certainly make secure programming hard not to do.
A good example of this approach is that taken by the OpenBSD project when it redesigned some of the low-level C library string manipulation functions to make them "more secure" in that they eliminated the programmer's ability to make certain, common, mistakes.
I don't look at this as a "stupid" versus "smart" issue. It's a "does my programming language help me do X or not?" issue.
So, stop blaming the programmer and find ways to make their already busy lives easy.
SQL escaping considered evil... (Score:5, Informative)
SQL Escaping is evil.
Why?
Because no user input should ever be executed. EVEN if it is escaped. The problem is that the escaping can be invalid and buggy and thus, insecure.
People should use parametric SQL statements. No excuses. In this manner, no escaping is ever necessary.
A separate issue is what to do about displaying user input. Here, things are more problematic, especially in the world of HTML. What would be nice is if we all got together and redesigned "the web" so that user input could be handled in a manner similar to parameters in SQL.
Obviously, there's a difference between data in tables and data in a formatted page. But I'm sure something could be done.
Re:The problem is .... (Score:4, Informative)
Re:mysql_escape_string, mysql_real_escape_string, (Score:3, Informative)
None of the above, use bind variables instead.
Re:Upload.php (Score:3, Informative)
Re:I have to agree.. (Score:5, Informative)
Perl ships with a fair amount of stuff. It ships with a package named DBI. You can do things like $rv = $sth->execute(@bind_values);. The documentation on it starts off with a convenient set of good examples which go like
$sth = $dbh->prepare("SELECT foo, bar FROM table WHERE baz=?"); $sth->execute( $baz );
PHP 5.2 ships with PDO [php.net] (PHP Data Objects) extension which can run with your example code provided you load the extension in your php.ini (yes, I know its a setting that is not done by default, but that argument doesn't hold water with PHP 5 anymore). PDO also supports the prepared statements [php.net] and parameter bindings [php.net] of which you speak, and along similar lines, you can also do transactions [php.net]. You should be clear about which version of PHP your referring to as PHP 4.4 is no longer considered the main release and also has not been updated since August while PHP 5 was last updated in November.
Though I can still agree that not all the choices made in the development were the best. AFAIK, every language has human developers and humans are not perfect, but we do do the best we can and have to continually aim to improve ourselves and the work we create.
Re:mysql_escape_string, mysql_real_escape_string, (Score:3, Informative)
When you're using like statements, you will have to pre-process things, yes. Most notably, escaping % and _ plus any other rules you want to implement (* to %, ? to _, explode on spaces with multiple LIKE statements to search on keywords, etc...).
Parameters are intended for user input. I certainly hoping you aren't allowing users to type functions in directly...
As for IN, I build up the placeholders using something like...
$placeholders = array_fill(0, count($search_params), '?');
$placeholders = implode(', ', $placeholders);
$query = "SELECT last_name, first_name FROM patients WHERE disorder IN ($placeholders) ORDER BY last_name";
Then bind the parameters when running the query. (I use ADODB [sourceforge.net] for PHP.)
Re:Who's fault? Zend's (Score:5, Informative)
From your post: "magic_quotes: This adds slashes to all input so that you don't have to sanitize it before it gets inserted into SQL."
BUT that is so totally the WRONG thing to do and a MISFEATURE, and the fact that the PHP developers made it a big feature of PHP shows why they and PHP suck. Think I'm being harsh? Read on.
This is what any sane programmer should do:
Each input source for YOUR application should be _individually filtered and escaped so that _YOUR_ application can handle the inputs correctly.
Each output destination for your application should be _individually_ filtered and escaped[1] so that the RECEIVING programs/entities can handle your app outputs correctly.
Example:
Say some data is http posted to a PHP web app, and the PHP app then sends the resulting data to a MySQL database, an Oracle database, syslog, and in some cases also emails some of that data to an email address, or redisplays the data in an HTML form on a web browser (required field left out).
magic_quotes would add slashes to the data when it enteres the web app, and that CORRUPTS the data. The resulting munged data _might_ still work for MySQL, but as is be incorrect for Oracle and SMTP (<lf>.<lf> needs to become <lf>..<lf>), data to syslog should have ctrl chars removed or escaped _appropriately_ and to be safe kept < 1024 bytes in length, and data to an HTML form shouldn't have the added slashes, but instead be appropriately quoted for HTML.
My proposal would have the web app filtering/escaping the data so the webapp can handle it, and then escape/filter stuff appropriately for MySQL, Oracle, SMTP, syslog and HTML. It seems like more work, but it is the correct way. It is less work in the long run especially if you make/use the appropriate libraries.
Once you understand the above, you should see why magic_quotes is so TERRIBLE, and why I have a low opinion of PHP and Zend.
And magic_quotes is not the only PHP misfeature that makes PHP PHP. You have named a few already.
Basically PHP makes doing the wrong thing easy, but the right things hard[2].
[1] by escaping/filtering I also include use of "SQL prepared/parameterized statements".
[2] After all these years it's still not clear what DB abstraction layer/library to use for PHP - there's the PDO vs PEAR DB thing, and PHP users are still resorting to crap like addslashes and magic_quotes. If each PHP coder writes their own DB library, anyone else taking over has to learn it. PHP should have learnt from the other languages mistakes.
For perl you use DBI, for Java you use JDBC.
All this crappiness has to be blamed on the developers who made PHP.
Security is about education (Score:3, Informative)
And this isn't just the fault of the developer. Unfortunately there's too many resources and options available, all of which have differing and conflicting methods for accomplishing something. Letting an uneducated developer decide which option to pick, I would agree, is not desirable.
But let's be clear on something: I design, build, and deploy enterprise-grade PHP applications for multi-million dollar projects. If there's a security problem discovered, it is my or my team's fault that we didn't protect against it. It's my responsibility to be educated enough to diagnose and prevent security threats in an application. I cannot say to the client, "PHP is inherently insecure", and expect that reason to fly and absolve myself of all responsibility.
I clearly do not understand why this excuse is the predominant argument here. "PHP is inherently insecure" is simply not true. PHP certainly doesn't encourage proper programming practices from the beginning, but by the same token, I can't recall a programming manual that doubled as an education tool in design and security practices that, combined, allowed me to write bulletproof code from the very beginning.
Re:PHP == fucked (Score:4, Informative)
How many times has this been said, and how many times do people need to point to examples like Wikipedia [wikipedia.org], YouTube (partially), Yahoo, Google, Facebook, and much more for proof of scalability?
And if you mean PHP doesn't scale architecturally, then you've demonstrated that you've never worked in an environment that did effectively scale PHP, or you simply failed at it. I'm going to guess both.