Beta

Slashdot: News for Nerds

×

Welcome to the Slashdot Beta site -- learn more here. Use the link in the footer or click here to return to the Classic version of Slashdot.

Thank you!

Before you choose to head back to the Classic look of the site, we'd appreciate it if you share your thoughts on the Beta; your feedback is what drives our ongoing development.

Beta is different and we value you taking the time to try it out. Please take a look at the changes we've made in Beta and  learn more about it. Thanks for reading, and for making the site better!

PHP Application Insecurity - PHP or Devs Fault?

Cliff posted more than 7 years ago | from the and-what-would-be-the-best-way-to-fix-the-problem dept.

PHP 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?"

cancel ×

200 comments

mysql_escape_string, mysql_real_escape_string, etc (2, Insightful)

Anonymous Coward | more than 7 years ago | (#17568202)

and addslashes. quick, which one is SQL secure?

Re:mysql_escape_string, mysql_real_escape_string, (3, Interesting)

FooAtWFU (699187) | more than 7 years ago | (#17568376)

Ooooookay. I've just been doing mysql_real_escape_string all day, so it had better work. :P

mysql_escape_string and mysql_real_escape_string should both work (assuming you're using MySQL, anyway), but the former is deprecated as PHP 4.3.0 in favor of the latter; it also does not respect the current character set setting.

If you looked at the documentation for addslashes [php.net] , though, it will tell you nice things like An example use of addslashes() is when you're entering data into a database even though there are special characters that it does not escape that can be used for SQL injection.

My beef with PHP is that it's full of junky functions like mysql_escape_foo() in the core distribution, main namespace, which don't even have a hint of data verification in 'em. I hear there's a neat database abstraction layer in PEAR, it even has prepared statements. But I'll wager there are plenty of PHP developers who haven't even heard of PEAR. Somehow, though, Perl seems to have managed to put together a decent standard distribution without this sort of mess...

Re:mysql_escape_string, mysql_real_escape_string, (1)

larry bagina (561269) | more than 7 years ago | (#17568454)

PEAR::DB is a nice database abstraction (somewhat like perl DBI). Although it's been superceded by PEAR::MDB2. PHP 5 has native PDO, which is also like DBI or DB, or MDB2, but each one has a slightly different syntax.

Every php project I've seen uses raw mysql_* functions or a reinvent the wheel (only this time, it's lopsided).

Re:mysql_escape_string, mysql_real_escape_string, (2, Insightful)

shoolz (752000) | more than 7 years ago | (#17569826)

Oh man your comment really bothers me. If you are relying on a PHP function to ensure user submitted data is trustworthy then you don't have PHP to blame if something goes Ka-blam due to a malicious user. I don't care what language you're coding in... if you trust user-submitted data without putting it through multiple rigorous tests, then you have nobody to blame but your naive self.

Re:mysql_escape_string, mysql_real_escape_string, (3, Informative)

mabinogi (74033) | more than 7 years ago | (#17568424)

Trick question.

None of the above, use bind variables instead.

Re:mysql_escape_string, mysql_real_escape_string, (4, Interesting)

AdamPiotrZochowski (736869) | more than 7 years ago | (#17569116)

FIRST : stop forcing prepared binded statements for all :

I dont mind prepared statements for when they are usefull, but they dont always work properly. And actually there are many cases where using them you actually lose power. Lets start with a simple example of the LIKE clause :

SELECT * FROM titles WHERE notes LIKE ?

For the unfamiliar, like clause allows me to do partial searches over strings (char/varchar in the sql world). The LIKE clause search string syntax is something of a simplified regular expression. This means that characters that usually have one meaning gain another one. For example the percentage sign becomes a wildcard (think dos/bash filename matching with '*', or regexp with '.*'). For example, all string starting with 'word' we would just search for 'word%'. Great, but how does prepare/binded statement know if the given percentage is to be escaped or not. It doesnt. So you end up doing own user parsing. You are back to square one. You need to still parse user input, so whats the point of binded/prepared statement? Another example is using power provided through fulltext index. Generally, string searching is slow. In SQL world we do an index, a cache to speed up looking. Strings have indexes, but that only speeds up searching for string that start with something (like in above example LIKE 'word%') but what if we want to search for something purely inside the string ?? then we could do LIKE '%word%' but thats slow, on the other hand, we could speed this up by various smart caching and indexing of the contents of the string. This smart indexing we call 'full text'. For example to see if a column contains some word or phrase we could just do

SELECT * FROM myData WHERE CONTAINS (column, ?)

all ok, right? NOPE, because it also could be :

SELECT * FROM myData WHERE CONTAINS (column, 'FORMSOF (INFLECTIONAL, ?)')

To explain slightly, the second examples tries to find words that are not exact, but very close. So for word 'good' another word 'best' could be used as an alternative (with a lower relevancy ranking). Great power?? Yes, but the first time the sql expects the query in the form CONTAINS ( notes , ' "word" ') notice single and double quotes while later its CONTAINS(notes, 'FORMSOF (INFLECTIONAL, word)') notice, no quotes allowed...

and dont even get me started with the

SELECT * FROM myData WHERE column IN ( ? )

The IN clause is a speed over a series of OR statements. I could write WHERE column = 1 OR column = 2 OR column =3 or I could just do it with WHERE column IN ( 1,2,3) . And now the question for the binding gurus. How do I do it with prepared statements ?? Do I create a loop and both generate the SQL and fill a flat array with the right amount of paramenters WHERE column IN ( ? , ? , ? , ? ) , or do I just send arrays within arrays.

SECOND : parameter binding through naming :

cant wait for when parameter binding can be done in a templated fashion, so that no longer order of the columns matters, currently the way you fill prepared statement with data matters by order of the data. It all should be done with associative arrays.

$sth = $__db->prepare ( "select * from myData where cond1 = ? and cond2 = ? " ) ;
$res =& $__db->execute ( $sth , array ( $userInput1 , $userInput2 ) ) ;

it should be done more like

$sth = $__db->prepare ( "select * from myData where cond1 = ?userInput1 and cond2 = ?userInput1 " ) ;
$res =& $__db->execute ( $sth , array ( "userInput1" => $userInput1 , "userInput2" => $userInput2 ) ) ;

There is no special need to input more -- if you want, use the first method just pass non associative array, and library should know to handle param binding in old way -- but for any larger querry, with dozens of parameters, this will be a big boon in readability. and this bring us to the second point :

THIRD : i want to see the final SQL :

Whenever I send something to the server I want to see what is the final statement that gets executed, not just on the SQL side, but also to have the executed query returned to me into my language of choice.


thank you

Re:mysql_escape_string, mysql_real_escape_string, (2, Informative)

VGPowerlord (621254) | more than 7 years ago | (#17569534)

To the first part:
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...).

SELECT * FROM myData WHERE CONTAINS (column, 'FORMSOF (INFLECTIONAL, ?)')

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:mysql_escape_string, mysql_real_escape_string, (2, Insightful)

AdamPiotrZochowski (736869) | more than 7 years ago | (#17569726)

SELECT * FROM myData WHERE CONTAINS (column, 'FORMSOF (INFLECTIONAL, ?)')

Parameters are intended for user input. I certainly hoping you aren't allowing users to type functions in directly...


For one of the servers I worked on this was the syntax for full text search. you would do CONTAINS ( column , param ) . The argument param was a string that contained additional properties for the full text search engine. One could add things like weights associated with words and phrases (hence double quotes), or ask to search for word variation (search for 'good' also matches 'best', since they are related). Ofcourse, this was all happening in one string, that param, so you had to, yet again, format your own string.

I am not advocating against using parametered sql calls, actually they are great, but I fear that on some level they are not much better than the magic_quotes=on, I fear as if they were an escape for lazy developers : use always, and your code will be unhackable. That was the premise of magic_quotes, it made developers feel safe, as if magically their code was unbreakable.

Now, for stored procedure calls, especially with parameters that double as both input and ouput, the parameter binding is the only way to go.

Cheers

Tool safety (2, Interesting)

nacturation (646836) | more than 7 years ago | (#17568218)

Saying that it's the programmers' fault for writing bad code is like saying being injured is the fault of a lumberjack for not knowing how to use a chainsaw which is dull and jerks a lot. It's much better to start with a tool that prevents such mishaps rather than being unsafe by default.
 

Re:Tool safety (1)

KillerCow (213458) | more than 7 years ago | (#17568278)

It's much better to start with a tool that prevents such mishaps rather than being unsafe by default.


But... performance... power... flexibility... waaaaaaaaaah.

Re:Tool safety (2, Funny)

qbwiz (87077) | more than 7 years ago | (#17568372)

Remember, it's PHP we're talking about here.

Re:Tool safety (2, Funny)

nocomment (239368) | more than 7 years ago | (#17568338)

His chainsaw probably wouldn't be so dull if he spent less time jerking.

Re:Tool safety (4, Interesting)

Beryllium Sphere(tm) (193358) | more than 7 years ago | (#17568350)

The aviation industry began making real safety improvements when they stopped regarding "pilot error" as the end of the story and began to fix ergonomics so that pilots weren't led into error.

Re:Tool safety (1)

mcrbids (148650) | more than 7 years ago | (#17568634)

The aviation industry began making real safety improvements when they stopped regarding "pilot error" as the end of the story and began to fix ergonomics so that pilots weren't led into error.

As a student pilot (I should have my license by Feb/March) I've read quite a number of crash analysis reports, as well as a large number of articles reporting "near misses", all in General Aviation. (lightweight, personal planes)

It's just amazing to me how many of these incidents are caused by things like the pilot shutting off the gas while in the air inadvertently.

I mean, what f--king retard puts a "kill gas" switch in easy reach of a pilot in the air? Can you name *ANY* scenario where it is an advantage to kill the fuel flow while in the air?

Another one: the stall. Why is it that the stall horn isn't rigged to the yoke, so that when you're about to stall (and potentially die, esp. during takeoff/landing) the yoke has pressure applied to it so that you have to actually try to stall the plane?

And, why not do something similar to put some pressure on the yoke the other way when you are getting close to maximum speed? (Vne)

Just stupid shiat that really, really, REALLY annoys me as a software engineer. How much of my time do I spend trying to anticipate the insane stupids done by my users?!?!? If I'm aware of a problem caused just twice by a stupid from a user DESPITE OBVIOUS WARNINGS, I change the button or something so I don't get the calls anymore.

Now, if somebody's life was on the line, don't you think they'd hide the damned "kill gas" switch, or at least make it require a concerted effort to turn it off? (think: automatic transmissions in most modern cars, which require you to push a button or something to get it out of drive into reverse or park)

It'd be nice if small plane designers thought about safety just a tad more.

Re:Tool safety (1, Funny)

Anonymous Coward | more than 7 years ago | (#17569216)

I mean, what f--king retard puts a "kill gas" switch in easy reach of a pilot in the air? Can you name *ANY* scenario where it is an advantage to kill the fuel flow while in the air?
I'd guess that an engine fire would be a pretty good time to use that particular switch.

Having read a bit about kit planes, I've gained some serious respect for some of those "f--king retard" aircraft designers. I think I'll take their designs over your, my friend.

Re:Tool safety (4, Insightful)

Cecil (37810) | more than 7 years ago | (#17570224)

There are two sides to that coin, you know. Aircraft designers tend to be extremely conservative, yes. But there's a reason for that.

Why do general aviation planes usually have extremely simplistic, 4-stroke big block engines with carbureators? Because they generally work. They do fail, but their failure modes are very well known, very obvious, and usually easy to fix. Those are important qualities, and I'm willing to bet that you underrate them. If you replaced the aircraft's engine with a modern fuel injected digitally controlled model, what happens if an injector clogs, or the computer goes insane? No one knows, and they're not eager to find out. If your carb ices, you can fix that. In-air, no less. It may be a less reliable design overall, but the failure modes are usually pretty tame. And that's worth a lot to an aircraft designer.

Taking one of your examples regarding the stall indicator/yoke... do you really want to take a piece of equipment which in correct operation is almost *never* going to get used, and hook it up to your primary controls? That's just *asking* for trouble. If the stall indicator ever gets jammed open (it is just a little metal flap after all, it's unlikely but possible), your "safety" measure may well crash the plane on its own.

It's not as easy as it looks. These people are not idiots, they simply have a lot of variables to consider and weigh. And they have a pretty solid track record behind them, too.

Re:Tool safety (0, Troll)

ChengWah (955139) | more than 7 years ago | (#17568514)

Just like it's vehicle manufacturers who kill and maim on the roads. If you can't or shouldn't drive then don't. Same applies to programming. Many programmers are optimists - poor misguided fools. If you write software, try to break it before you release it, or don't bother writing it in the first place.

Interesting... (1)

sheldon (2322) | more than 7 years ago | (#17568606)

Given your example of a chainsaw, you might want to google words such as anti-kickback chain, chain brake, hand guards and/or just the general chainsaw safety keywords.

You might learn something.

Re:Tool safety (1, Insightful)

pyite (140350) | more than 7 years ago | (#17568636)

Saying that it's the programmers' fault for writing bad code is like saying being injured is the fault of a lumberjack for not knowing how to use a chainsaw which is dull and jerks a lot. It's much better to start with a tool that prevents such mishaps rather than being unsafe by default.

Wow. If that's your actual, honest opinion, you scare me. It looks like "personal responsibility" is all but nostalgia for people. You know, I can make a chainsaw that I can guarantee almost 100% won't cut you, but it probably won't cut any wood either. In fact, while we're at it, we should make chefs use plastic cutlery, because gosh darn it, they might hurt themselves with those big, sharp, metal blades.

Tools are tools. While tools can certainly be poorly designed, they should never be crippled just because people might "hurt themselves." This applies for real tools and it applies for software.

Re:Tool safety (5, Insightful)

VGPowerlord (621254) | more than 7 years ago | (#17569296)

Have you ever used PHP? If not, take a look at the following features:

  1. addslashes() [php.net] function - Most references say to use this to quote data before putting it into a database. Not only is it The Wrong Way To Do It (twwtdi) according to the SQL standard, but different vendors' databases need different values escaped.
  2. Magic Quotes [php.net] ini settings. magic_quotes_gpc is the most important one. When enabled, it runs addslashes() on all GET, POST, and cookie input. It is on by default in php.ini-dist, off by default in php.ini-recommended. Which brings up my next point...
  3. The programming environment is not consistent. An INI file [php.net] controls the programming environment. Turning on things like Safe mode [php.net] and open_basedir can cause previously working code to suddenly fail. Of course, php.ini-dist has display errors [php.net] turned on by default, so anyone visiting that page will see the location of your file, the line that has the error, and which error it is... Which brings up the next point:
  4. Security is secondary to convenience. See Using remote files [php.net] , which is enabled in both ini files by default. See also Magic Quotes as described earlier. Reading up on the deprecated Register Globals [php.net] is informative, as it was on by default up until PHP 4.2.0. I've also mentioned display_errors, which is on in php.ini-dist.

    Here's a disturbing fact: php.ini-dist is the more ocmmonly used of the two inis, at least for shared hosting. I'll let you consider the implications of that while I summarize things.
To summarize: The PHP team has made a number of questionable decisions over the years that makes it much easier to write a security hole than it should be.

Re:Tool safety (0)

Anonymous Coward | more than 7 years ago | (#17569958)

From the page linked to for 'display errors':

display_errors boolean

This determines whether errors should be printed to the screen as part of the output or if they should be hidden from the user.

Note: This is a feature to support your development and should never be used on production systems

If you're too lazy to actually go through the conf file that's kind of your own problem, no?

Upload.php (0)

eldavojohn (898314) | more than 7 years ago | (#17568238)

Disclaimer, I am not a PHP developer!

You know, I was thinking about this the other day. When I tried an online PHP tutorial a while ago, it turned out that it was trying to get me to use an upload.php file to put files on your webserver to try out. Tsk tsk, lazy developers!

Now, the tutorial showed me this but I'm sure nobody uses it in real life, right? Well, explain this then [google.com] !

Now you may be able to convince me that some are fairly safe. That they check file type and all that jazz. Problem is that I know not everyone is being safe.

I know this doesn't nearly cover this issue at all ... but for some reason in my mind I associate this upload script with PHP. Is it taught to everyone? I'm not sure, having received no formal training. I guess this is just anecdotal evidence of some lazy developers in PHP. But can you really criticize a language for its users being stupid? Probably since I've seen arguments all over about which language is "safer" than others.

agreed! (1)

numbsafari (139135) | more than 7 years ago | (#17568432)

I have to say, part of the quality of the "tutorials" and documentation provided by the language proponents should probably be taken into consideration.

For example, a while back I was reading the Microsoft training materials on .NET Web Services. The example instructed the developer that they should generate their primary keys by selecting the MAX of an int column, adding one and then inserting the new record.

I can understand not wanting to confuse someone with the complexities of concurrent programming when you're just trying to introduce them to the UI for the compiler. But seriously, there was a two paragraph description of how to do this. One could certainly fit in a description of using identity columns or some other reasonable approach rather than selling this other mess as a good idea.

And so, when MS complains that their devs get no credit... well... one only has to point to the quality of the manual they were supposed to learn from.

Sounds like PHP suffers from the same problem.

Re:Upload.php (2, Informative)

temojen (678985) | more than 7 years ago | (#17568464)

Erm... "Upload.php" is a logical thing to call a script which accepts an upload... it doesn't necessarily mean they all do the same thing. Ever noticed that there are an awful lot of C functions called "char** parse(char* s)" even though many programs have errors in their parse function?

Re:Upload.php (1)

The MAZZTer (911996) | more than 7 years ago | (#17569078)

You are making the troubling assumption that ONLY developers are going to need to upload files to their sites.

How else are authorized end users going to be able to upload files for your script to process? To risk overusing a cliche, this is Web 2.0 here! The majority of users don't care about what FTP is, nor do they want to learn something new just to post a file to a website!

An upload script is perfectly fine as well as the security behind it stops people from posting or touching files they shouldn't.

The problem is .... (5, Insightful)

lambent (234167) | more than 7 years ago | (#17568264)

The problem is that so many neophyte progrrammesr jump into PHP to create something visible and useful. Which they succeed in doing, more often that not, I guess. But without a proper background in security and proper practice, there's a ton of vulnerabilities that get created, accidentally, over and over again by every new PHP programmer.

The same can be said about any other language. Take for instance, C. Very easy to create working code that's vulnerable as hell. Is this the original author's fault? Of course not. I'm sorry that whoever chose to write a webapp in PHP is ignorant of basic security principals, but it's not up to the coders of PHP to protect us from ourselves.

Re:The problem is .... (3, Informative)

Schraegstrichpunkt (931443) | more than 7 years ago | (#17568402)

Blah blah blah. I've written code in both PHP and C, and writing secure code in PHP is harder, because you have to work around the insecure C code it's written in. No amount of rhetoric is going to convince me otherwise, because writing PHP code is my job, and I know better.

Re:The problem is .... (3, Insightful)

lambent (234167) | more than 7 years ago | (#17568564)

Good for you. Writing PHP code is part of my job, too. As is writing C, perl, java, python, and anything else you can throw at me.

It all comes down to knowing what you're doing in the language you're coding in. If you're not good enough to sanitize, error check, bounds check, mem check, fault check, and whatever the hell else could go wrong, you have no business coding.

It's YOUR problem, not anyone else's. Don't pass the buck. If you don't like that, choose another language.

Re:The problem is .... (4, Insightful)

Coryoth (254751) | more than 7 years ago | (#17569228)

If you're not good enough to sanitize, error check, bounds check, mem check, fault check, and whatever the hell else could go wrong, you have no business coding.

I think the point is that we're all human and we all make occasional mistakes even with the best of intentions. There's plenty of code out there written by very experienced C programmers that still has buffer overflows and other glitches. That means that having a language that has the facility to make such errors easier to catch and correct early is a good thing. That means that having a language that pushes you toward secure practice by not having sloppy easy ways to do things is a good. Yes, we could all, in theory, write perfectly secure error free code in C or PHP or whatever, but in practice we don't - no one does. Languages that encourage best practice by default and provide the tools to catch errors earlier (with, say, design by contract) are a good thing if security is important. We're all human, and can use all the help we can get.

Re:The problem is .... (2, Insightful)

Schraegstrichpunkt (931443) | more than 7 years ago | (#17569526)

It all comes down to knowing what you're doing in the language you're coding in. If you're not good enough to sanitize, error check, bounds check, mem check, fault check, and whatever the hell else could go wrong, you have no business coding.

"Sanitized" is a generous way of saying "not binary-safe", which also means "not internationalized" and "doesn't work in edge cases". Most of the time, if you have to \"sanitize\" input, instead of accepting and properly encoding <em>any</em> possible input, you\'re doing something wrong.

As for error checking, bounds checking, "mem checking" (what is that? avoiding memory leaks?), "fault checking" (how is that different from error checking?), etc, those are tasks that a computer can do much more reliably than any person. If, realizing that, you still can't see how hopelessly stupid your argument is, then I suspect you're the one who has no business coding.

You would totally fail at investigating plane crashes.

Re:The problem is .... (1)

Jack9 (11421) | more than 7 years ago | (#17569414)

I've written code in both PHP and C, and writing secure code in PHP is harder, because you have to work around the insecure C code it's written in.
I wrote my first DB abstraction in PHP/FI in 1997. I've never ever used PHP for anything other than web development as it's not explicitly designed for anything else. The previous quote is from someone doing what any professional PHP programmer knows not to do. Trying to program non-web applications in PHP (forgive me if you mean you arent experienced enough to make non-exploitable webscripts, I'm giving you the benefit of the doubt). Yes, it's possible to make full blown PHP applications. You can also intentionally insult your company's president at a corporate-sponsored party. A programmer acting irresponsibly is not the fault of a language.

This is easy to test empirically (4, Interesting)

Schraegstrichpunkt (931443) | more than 7 years ago | (#17568280)

Take 100 programmers selected randomly, and instruct them all to write a given application, but have 20 of them write the code in PHP, 20 write the code in Python, 20 write the code in Java, and 20 write the code in C++, and 20 write the code in Perl. Then analyze the resulting code.

I have to agree.. (1)

QuantumG (50515) | more than 7 years ago | (#17568292)

PHP provides a means to access the fields of a form submit as strings.. not as integers.. not as dates.. not a html input boxes.. as strings. The default and common usage of accessing the fields of a form submit should require that you provide a type. Similarly, the default and common usage of accessing the fields of a form submit should do SQL escaping for you. If you find out you have a problem with that escaping, you should be able to turn it off... but the escaping should happen by default and should be built into the library call.

SQL escaping considered evil... (5, Informative)

numbsafari (139135) | more than 7 years ago | (#17568370)

I kind of agree with where you are going, but I would add the following point:

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:SQL escaping considered evil... (1)

Jesselnz (866138) | more than 7 years ago | (#17569082)

People should use parametric SQL statements. No excuses. In this manner, no escaping is ever necessary.

The problem is that most hosts are still using MySQL 3, which doesn't support prepared statements. There's really no excuse for that, considering that MySQL 5 is very stable now.

Re:SQL escaping considered evil... (1)

blincoln (592401) | more than 7 years ago | (#17569128)

Because no user input should ever be executed.
(snip)
People should use parametric SQL statements. No excuses.

Agreed, however:

In this manner, no escaping is ever necessary.

You're still going to have problems in languages like Javascript that have methods like "eval()". I don't know if PHP has one (I'm just starting to look at it this week, I'm not a fan of web development in general), but if it does, all the SQL escaping in the world won't necessarily matter. You can't escape for multiple different languages simultaneously unless you reduce the character set down to something like alphanumeric + period and comma.

Re:I have to agree.. (1)

MysticOne (142751) | more than 7 years ago | (#17568388)

But PHP doesn't really have types, nor do HTML forms (aside from the differences between buttons, check boxes, etc.) And always escaping for SQL? That's the job of the SQL libraries, not the language itself. At some point a developer has to take responsibility for what they write, and they should handle data appropriately.

Re:I have to agree.. (2, Insightful)

FooAtWFU (699187) | more than 7 years ago | (#17568538)

PHP pretty much invites you to be insecure with MySQL. They ship with this tempting mysql_query() that takes as an argument... a single string. (well, and a connection ID). To get something in there, you need to do something like mysql_query("select * from foo where whatever = '$var'") -- and remember to have $var properly escaped. PHP does not give you a pretty library with prepared statements, parameter binding, and such. There's a nice DB and MDB2 package available on PEAR, but PHP doesn't ship with those. It ships with the compile option --with-mysql.

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 );

You can write code in PHP that's perfectly secure, you can do just about anything in PHP you could do in Perl (props for being Turing-complete, I guess), and yes, it ultimately is the developers' responsibility to secure their applications, not PHP's. That doesn't change the fact that PHP is an ugly mash-up of a language with Bad Choices just lying around in a scrap heap on the ground begging to be used. It's just about as organized as a scrap heap, too... (insert generic rant about naming conventions, parameter ordering, and such).

Re:I have to agree.. (1)

MysticOne (142751) | more than 7 years ago | (#17568582)

I don't disagree that PHP is very ugly at times (with function names that are anything but consistent). I agree with pretty much everything you said, and that it IS easy to do bad things in PHP. But I do still think it's the developer's responsibility to know their language and use it appropriately. Also, does Perl actually come with DBI? I was thinking you had to install it separately from the base distribution (i.e., via CPAN or something).

Re:I have to agree.. (1)

VGPowerlord (621254) | more than 7 years ago | (#17569362)

You have to install DBI separately, but CPAN will automatically install DBI when you install any DBD module.

Re:I have to agree.. (0)

Anonymous Coward | more than 7 years ago | (#17568702)

There is such a thing as http://www.php.net/pdo [php.net] you know? Maybe you should look into a current version of PHP :-)

Re:I have to agree.. (1)

FooAtWFU (699187) | more than 7 years ago | (#17568882)

There is such a thing as http://www.php.net/pdo [php.net] you know? Maybe you should look into a current version of PHP :-)
Hasn't been around long enough. It takes longer than a year (+ 1 month 17 days since PHP 5.1.0) to change your stripes. PHP 4 is still the standard that you need to write your code to if you want to be sure Average Joe can run it at his mom-and-pop web host without funky settings. PHP 4 is still the language of dozens of tutorials on the 'Net. PHP 4 is still running dozens of production sites that would break if you switched to PHP 5 all of a sudden.

And it will take more than this to get PHP a reputation of security. Maybe once they've deprecated (or even removed) the old cruft like mysql_connect and put great big bold notices on the documentation pages of the old functions about "DON'T USE THIS" and things like addslashes() and such that say, "use PDO instead", and once this news works its way down the grapevine... then we can talk.

Re:I have to agree.. (1)

lewp (95638) | more than 7 years ago | (#17569628)

I know that. I also know about ADODb and PEAR::DB. I also don't write exploitable DB code.

The people who give PHP its bad rap don't know about those things, or why they should use them, and they outnumber me 10:1. Unfortunately, when they go to http://us2.php.net/mysql_query [php.net] to look up what is quite possibly the only PHP function they actually know, there's nothing except some gibberish in a comment halfway down the page with a poorly-written DIY solution and no link to the resources the clued folks know about.

Is it the programmers' fault for being an idiot? Sure. I'm no friend of the morons. Burn them at the stake. Is it the PHP developers' fault for not directing said morons to the right way of doing things? Yes, because they originally caused the problem by making the only installed-by-default mentioned-in-the-docs interface to the most popular database one step above the C library interface without drilling the possible security issues into their skulls (notice there's no mentioned about security on that page at all), while also billing the language itself as the grandma-easy web language.

I write PHP for a living (and Perl, Python, Java, or Ruby when I can sneak it into a project without making waves). I've been around it for several years. I know what I'm doing. Most of the people who are writing PHP, and even most of the people who are writing free PHP software that is being released to a wider audience don't meet those criteria. The PHP developers themselves share a large responsibility for creating this situation, and they need to be conscious of it every step of the way.

Re:I have to agree.. (5, Informative)

quadra23 (786171) | more than 7 years ago | (#17568852)

PHP does not give you a pretty library with prepared statements, parameter binding, and such. There's a nice DB and MDB2 package available on PEAR, but PHP doesn't ship with those. It ships with the compile option --with-mysql.

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.

Shared hosting? (1)

tepples (727027) | more than 7 years ago | (#17569922)

PHP 5.2 ships with PDO (PHP Data Objects) extension

Which PHP 5.2 shared web hosting companies do you recommend?

You should be clear about which version of PHP your referring to as PHP 4.4 is no longer considered the main release

Tell that to the majority of shared hosting companies.

Re:I have to agree.. (0)

Anonymous Coward | more than 7 years ago | (#17569288)

> Perl ships with a fair amount of stuff. It ships with a package named DBI.

Actually, Perl doesn't come with DBI. It's just the first thing most people hit CPAN to install.

Re:I have to agree.. (1, Insightful)

Anonymous Coward | more than 7 years ago | (#17568506)

you're the kind of idiot that magic quotes was created for.

Re:I have to agree.. (1)

binford2k (142561) | more than 7 years ago | (#17568726)

Why should accessing form fields do SQL escaping? What if you aren't using SQL? Shell escaping is different. Or what if you're using a database that escapes strings differently than MySQL? (yes, believe it or not, there are other database servers).

If there is auto SQL escaping taking place, it should be right where it's needed, in the db layer.

Re:I have to agree.. well... not really. (1)

sydney094 (153190) | more than 7 years ago | (#17570182)

I have to disagree with you. Form values are sent over the line as strings, and as such, they should be treated as string by the base language/framework. I mean, who's to say that when you enter "3125551212" on a form, that you are talking about an integer number or a phone number string?

As far as SQL injection, every RDMBS access method that I know of allows the developer to execute arbitrary queries. The trick isn't to have automatic SQL escaping (again, the language/framework isn't smart enough to differentiate when my " ' " should really be escaped), but rather to "encourage" the developer to use typed (named) parameters in the SQL.

It isn't the language, it's the dev. More accurately though, since PHP is largely pitched to beginners, it's really the documentation and book authors.

what's the purpose of a language, anyway? (3, Informative)

numbsafari (139135) | more than 7 years ago | (#17568300)

The question, as I see it, is what really is the purpose of a programming language?

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:

PHP is a widely-used general-purpose scripting language that is especially suited for Web development and can be embedded into HTML.
So, PHP claims to be "especially suited for Web development". Given that one of the primary concerns of web development should be security, I would expect that the language, and the core libraries that are packaged with it, would promote and encourange safe programming practices.

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.

Re:what's the purpose of a language, anyway? (0)

Anonymous Coward | more than 7 years ago | (#17568380)

I believe the primary purpose of a language suited for web development is to deliver content to a browser. Thats just me though.

Re:what's the purpose of a language, anyway? (2, Insightful)

numbsafari (139135) | more than 7 years ago | (#17568460)

Sure, but what good is it if the content happens to be spyware or a root exploit?

I mean, you could make the same degenerate argument about Windows and OS's, but something tells me it would sound just as lame.

Re:what's the purpose of a language, anyway? (3, Interesting)

MysticOne (142751) | more than 7 years ago | (#17568422)

Is it really that PHP makes it that hard to be secure, or that it makes it easy to do whatever you want, thereby allowing a lot of lazy people to take the easy route? I think the developer (writing code in PHP, not necessarily the developers of PHP) have to take responsibility for the things they write. If you're trusting user-entered data without escaping it and verifying its validity, shame on you! If you're doing other silly things that make it possible for people to h4x0r your systems, that's also largely the fault of the person writing the offending web application. I have nothing against making PHP more secure, but what does this entail? Not allowing you to do the things that make PHP flexible and fun to work with? I think the resulting language would be about as useful as safety scissors.

Re:what's the purpose of a language, anyway? (2, Interesting)

numbsafari (139135) | more than 7 years ago | (#17568528)

Agreed: developers should absolutely take responsibility for the code the write.

And people should take responsibility for the cars they drive and the pollution they create.

Of course, it would seem to me like a lot of people believe that there's a certain social value in asking the producers of cars and heavy equipment to improve the quality of their products.

As with anything, one should select the right tool for the job they are trying to do. If you need to write a complex site, pick a tool that allows you to do things that are more complex. Of course, doing so means you need to be aware of what that complexity means and take responsibility for the increased risks.

However, PHP sells itself as the "easy to learn", "user friendly language" of the web.

As someone noted earlier in the thread, user friendliness often times includes safety matters. Sometimes, safety scissors are warranted.

Re:what's the purpose of a language, anyway? (1)

Shados (741919) | more than 7 years ago | (#17568628)

Think of it this way: You know of IE's ActiveX, yes? You know how much of a security nightmare they are? Yet, they exist to make developing for IE easier and more flexible, and easy, without having to worrie about all these security settings, sandboxes, certificates, blah blah blah. Look what happens from that. Easy, flexible and fun should be balanced with robbust and well designed, thus later environments fixed that, but we still today live with the ActiveX mess.

Same thing here with PHP. Yeah, its fun and easy that you can set it so your post variables are directly converted to PHP variables. Woohoo, I can have a textbox called MyField, and bang, retrieve its data from $MyField (or something, its been a while). How fun, flexible, and convenient. ...

Its also one of the worse security nightmares ever. The slightest mistakes in your code design, and BANG, all kinds of issues. Its just NOT WORTH IT. Yes, ActiveXs have interesting and powerful uses. But -its not worth it- when weighted against the problems. Same thing here with PHP. A lot of things in PHP are rediculous design choices, and allowing these things at ALL serves no purpose, aside from allowing new programmers from thinking they're "L33t" while shooting themselves in the foot repeatedly, without ever knowing it.

PHP isn't the only environment with these issues: why the bloody hell does VB.NET even allow you to code without option strict. WHY?! So people can waste memory left and right, make casting errors all over, and have hundreds of lines of code with problems that cannot be checked by the compiler? All in the name of being more friendly? -NOT WORTH IT-.

See where I'm coming from?

Re:what's the purpose of a language, anyway? (1)

VGPowerlord (621254) | more than 7 years ago | (#17569384)

To be fair, PHP disabled the whole "post variables become PHP variables" by default back in PHP 4.2.0.

Also, error_reporting(E_ALL); will make PHP throw warnings (but not die) when it runs in to undefined variables.

Re:what's the purpose of a language, anyway? (1)

jrockway (229604) | more than 7 years ago | (#17570186)

> Is it really that PHP makes it that hard to be secure

Yes, it really is. Perl has had "taint mode" forever. This forces the programmer to validate all input before passing it to things like database queries or open(), system(), etc. Instead of a coding error causing you to lose all your data and take out your web server, the program will just exit. Having the compiler double-check your work is always easier than wondering if you got everything.

Adding to that is the fact that PHP has never had a sane database interface, even though it's freakin' designed to interface with databases! Code like: mysql_query("SELECT * FROM foo WHERE bar='". sqlClean($bar). "'") is just plain hard to read and is just plain prone to error. Give me something like query("SELECT * FROM foo WHERE bar=?", $bar) any day. The compiler should do the heavy lifting for me -- as a programmer I should worry about solving problems. Navigating through spaghetti like "'".clean($var)."'" is not something I ever want to do.

Obviously, this is just the tip of the iceberg... I could write 1000s of pages about PHPs failings.

Re:what's the purpose of a language, anyway? (2, Insightful)

lphuberdeau (774176) | more than 7 years ago | (#17568656)

Of course the programmer is not to blame, but the PHP Group can't do everything. I've attended to multiple conferences, read PHP magazines and such. The community does encourage good practices. Security is discussed all the time, with techniques to structure code in order to avoid problems. The Zend PHP Certification contains a section on security. The problem is that the entry level programmers using PHP don't spend $800 to attend a conference. They don't pay $50/year to subscribe to a specialized magazine. They don't buy one of the two great books on PHP Security. Instead, they surf the web and grab the tutorials written by anyone and use the one that looks the most simple, which is obviously a bad choice. The PHP Group has no control over what is published on the web.

Re:what's the purpose of a language, anyway? (1)

jrockway (229604) | more than 7 years ago | (#17570230)

I trust PHP security experts about as far as I can throw them. This guy [chxo.com] is the author of a PHP security book and I found many many severe security problems [seclists.org] in his published code. To parse XML, for example, he cleverly injected some PHP into the string containing the XML fetched from an untrusted server, and then eval()d the whole mess. Needless to say, that's not a very secure way to parse XML!

If this is how published security experts write PHP, I pray to god that I never have to look at any entry-level PHP.

A bit of both, I'd say. (1, Insightful)

Anonymous Coward | more than 7 years ago | (#17568346)

We need work on both sides. Programmers need to know how their apps could be exploited (cross server scripting, remote includes, SQL injection, etc.) The platform, on the other hand, should make it harder for these vulnerabilities to occur.

Possible options for SQL injection attacks, for example, include Perl's "tainting" mechanism. Where does this string come from? The outside world? Right, it's considered tainted. Any manipulation that puts the string (or even just a part of it) into another causes that string to be tainted as well. No tainted string can be sent as an SQL command to a database, although it can be sent as a parameter. If you absolutely have to include it in an SQL command, there could be a function that de-taints the string: so that quotes and similar are escaped, to remove the ambiguity, for example.

For example, instead of constructing a string 'SELECT * from FOO where BAR="(string from the outside world)"', you'd construct a string 'SELECT * from FOO where BAR=:parameter1'. You'd then construct a set, saying parameter1 = '(string from the outside world)', much like Python's dictionaries. Then you'd call the database: execute this SQL command, and these are the parameters to go with it.

Last time I looked, you could do the latter part (but not the former part) with Oracle databases under PHP, but nowhere else. Why not? This is a very basic way to avoid 99% of the SQL injection cases out there ...

Re:A bit of both, I'd say. (1)

gradedcheese (173758) | more than 7 years ago | (#17568990)

For MySQl, PHP 5 and its MySQLi extension provide prepared statements and the like to improve things in the way you're suggesting. Earlier versions really didn't, and on top of that there is the magic quotes 'feature' that really mixes things up (and, I hear, is due for removal soon).

My main gripes have been the complete lack of namespace support, dumping everything into one global space and making it relatively easy to screw up. PHP also plays fast and loose with variables, which at times is convenient but often leads to ambiguities that can have unforeseen consequences. Things like using uninitialized variables are marked as a very low warning priority (not shown by default). Pre-PHP5, the OO features were very lacking, often making it pretty worthless to try to write code that way. Not necessarily security issues, but they definitely contribute.

Re:A bit of both, I'd say. (1)

Mr. Slippery (47854) | more than 7 years ago | (#17569234)

Last time I looked, you could do the latter part (but not the former part) with Oracle databases under PHP, but nowhere else.

Sounds like PEAR's DB module [php.net] or MDB2 modules [php.net] .

Re:A bit of both, I'd say. (1)

jrockway (229604) | more than 7 years ago | (#17570242)

Nobody uses those, though, because they're buggy, broken, and braindead.

You are all lazy programmers! (0, Troll)

Karaman (873136) | more than 7 years ago | (#17568458)

You are too lazy to create secure code, so you blame PHP, LOL :)

I have been using PHP for 5 years now and I always checked
how my code worked, whether it was safe enough, etc. etc. ....
I dont rely on others to do my job!

Well, I dont say there are no stupidities or bugs or whatever in PHP,
but when you write insecure code, you should not blame the language
you are writing in!

Blame yourselves that you have not read enough, that you have not
tested enough, or that you are not lucky enough!
Then sit on your butt and rewrite those unsafe lines of code!

p.s. If you feel you don't have the ability to write good PHP code, blame yourselves again!

Re:You are all lazy programmers! (2, Interesting)

Shados (741919) | more than 7 years ago | (#17568566)

The problem here, is that if you cannot depend on the framework for SOME stuff, why are you even using a framework? Thats like if in Java or .NET you had to constantly worrie about memory leaks (you actualy do, to some light extent, but thats beyond the point), then when someone complained about the framework not handling them, people would go "dont blame the framework, blame yourself!". The framework is supposed to handle these things.

The absolute worse thing ever in PHP is how until recently, SQL injection could happen because there was incredibly poor prepared statement support. Good frameworks encourage the use of prepared statements to the extreme. It was possible to use in PHP4, but certain extras had to be added, and it was rare to hear about them in tutorials, etc (thus the blame was also greatly on the community). This, along with the far too common default setting of mapping post variables to variables directly were major things that I definately think CAN be blamed on PHP and its community.

.NET 1 and 1.1 had a very well known flaw of this kind. The datagrid, when a column was configured as invisible, would still render the HTML for the data in that column, but simply not display it. This allowed the data to be seen in the source, but not on the actual page. This lead several developers to hide columns to have secret data in memory to work with on the server side, thinking the user had no access to it. Of course, a GOOD programmer would think of that and use a different method to hide the data securely. That doesn't change that it was an insecure and poor design choice in the .NET framework, and it was fixed in .NET 2.0. So yes, the framework was to blame. Same with PHP's issues. And they are severe. The community however, make them 10x worse than they should be.

Re:You are all lazy programmers! (1)

VGPowerlord (621254) | more than 7 years ago | (#17569424)

P.S. If you don't have a call to get_magic_quotes_gpc() in your program somewhere, you don't have the ability to write good PHP code.

Re:You are all lazy programmers! (1)

Karaman (873136) | more than 7 years ago | (#17569702)

You have never been so right, mate!

it really is the dev's fault (0, Flamebait)

ILuvRamen (1026668) | more than 7 years ago | (#17568522)

If you leave it wide open for SQL injections when you could just filter out semicolons is absolutely the developer's fault. The code is gone by the time the page gets to the user for God's sake, it's not a horribly insecure language if you know how to use it. Languages aren't there to babysit someone who knows nothing about proper security, they're there to do the maximum amount of things. Adding securit restrictions would just piss people off and get in the way of people who want to do things other ways

Re:it really is the dev's fault (1)

Rycross (836649) | more than 7 years ago | (#17568648)

If you think just removing semicolons prevents sql injection, then I have bad bad news for you. Your code is insecure.

See thats the point. The reason we use higher level languages in the first place is partly so that we have a safety net. Its not just a matter of developer competence. Nobody is perfect. Everyone makes mistakes. Ideally the language should be able to catch them sooner rather than later. Why would I want to use PHP if one mistake could hose my security?

Noones saying the developer is blameless, but saying that because the developer is ultimately responsible, the language has no blame, is a cop-out.

Re:it really is the dev's fault (0, Troll)

ILuvRamen (1026668) | more than 7 years ago | (#17569422)

oh sorry, I meant to type out my entire security policy for PHP but it was a bit longer than that. Shut up, it was an example

Re:it really is the dev's fault (0)

Anonymous Coward | more than 7 years ago | (#17569510)

If you remove semicolons at all, you're a retard. Use PHP's equivalent of PreparedStatement, stupid.

Re:it really is the dev's fault (1)

tepples (727027) | more than 7 years ago | (#17569956)

Use PHP's equivalent of PreparedStatement

Do most shared hosting companies use PHP versions that include PDO?

Yes (3, Insightful)

Rycross (836649) | more than 7 years ago | (#17568578)

The answer is yes. Obviously, developers are ultimately responsible for writing secure code, but that doesn't mean we can't damn programming languages that fail to encourage good coding practices. I'm including libraries and official tutorials in this.

Fact of the matter is, real security comes from having many layers. Having a programming language that directs you to safe practices and actively prevents you from creating unsafe code is the first line of defense. Yes, the programmer needs to educate him or herself on how to write secure code, but given that people are not perfect, the language should have a safety net.

There's a reason that we've moved away from languages such as C, except when necessary.

And from what I've seen, PHP has really encouraged bad programming practices. Preferring escaping SQL strings instead of proper parameterized queries, register globals, etc.

Re:Yes (1)

bill_mcgonigle (4333) | more than 7 years ago | (#17569490)

but that doesn't mean we can't damn programming languages

Reminds me of Spock in Star Trek IV. :)

Who's fault? Zend's (4, Insightful)

kestasjk (933987) | more than 7 years ago | (#17568642)

I've audited quite a lot of PHP, written an article [kuliukas.com] on PHP security from the hackers perspective, and done quite a lot [phpdiplomacy.net] of PHP development, and I've never come across an security problem that you could blame the developers for!

It's always the developer assuming something about PHP or the PHP environment but getting it wrong; you can argue that the developer should know, but there are so many gotchas in PHP, you have to be an expert to be aware of them all. (I've listed some in a previous post [slashdot.org] on /. , and won't repeat myself here).
This isn't right for any language, but a language which web applications run on?! The most hostile environment to develop for is not the place for a language that makes it so easy to trip up!

The fault, for the vast majority of PHP security problems, is completely Zend's. Zend needs to give security priority over backwards compatibility, and get rid of all of their problems that developers repeatedly trip up on.

Re:Who's fault? Zend's (2, Insightful)

Mr. Slippery (47854) | more than 7 years ago | (#17569504)

there are so many gotchas in PHP, you have to be an expert to be aware of them all. (I've listed some in a previous post on /. , and won't repeat myself here).

Looking at your list, I see complaints about:

  • magic_quotes and register_globals, which are options that can be turned off: register_globals is off by default, and has been that way for a long time. Anyone who turns it back on deserves what they get. It's a dead issue. magic_quotes is headed for the same fate in PHP 6. They seemed like good ideas at the time the web as young; they turned out not to be.
  • "Only critical errors are reported...unless you specifically turn up the error_reporting level" Configurable logging and reporting is a feature, not a bug.
  • "fopen_urls: By default you can include scripts hosted on other websites!" I'll agree, that should probably be off by default. But a developer has to be naive or dim to either use an URL include, or include a variable in the include directive (and thus introduce the possibility of a URL inclusion) without being damn sure what they're doing.
  • "Inconsistencies: What one function does can never be applied to what another function does; you can never assume anything with the PHP library and always have to keep a browser window with the PHP manual handy. Using a function without carefully reading up what it does, even when it's very similar to another function you're familiar with, is asking for trouble in PHP." And in C (bcopy versus memcpy, anyone?), and C++, and Perl, and Javascript, and... In fact, most of these "inconsistencies" stem from trying to stay consistent with functions borrowed from C, Perl, et cetera. That's a good goal.
  • "Input checking is difficult...Do you want htmlentities() or htmlspecialchars()?" Depends on what you want to do, now, doesn't it? Developers have to know what conditions they need their data to adhere to, and PHP gives them a variety of tools to make it fit those conditions. Feature, not a bug.
The most hostile environment to develop for is not the place for a language that makes it so easy to trip up!

It's easier to trip up badly in C (by commiting some memory buffer error) or Perl (by writing line noise code that you can't understand a week later) than PHP. But it's no longer fashionable to bash those languages.

Zend needs to give security priority over backwards compatibility, and get rid of all of their problems that developers repeatedly trip up on.

Apparently what you see as "problems", others see as features.

Re:Who's fault? Zend's (4, Insightful)

kestasjk (933987) | more than 7 years ago | (#17569708)

magic_quotes and register_globals, which are options that can be turned off: register_globals is off by default, and has been that way for a long time. Anyone who turns it back on deserves what they get. It's a dead issue. magic_quotes is headed for the same fate in PHP 6. They seemed like good ideas at the time the web as young; they turned out not to be.
Yes, but if you develop on a server which has magic_quotes on, and you deploy on a server that has it off, your code won't behave as expected. You have to be aware of magic_quotes before writing anything in PHP, if you want to be safe.
Same goes for register_globals; and it's hardly a non-issue as it's enabled just about everywhere in the name of backwards compatibility. In the article I wrote the site that got exploited had a vulnerability exposed by register_globals.

"Only critical errors are reported...unless you specifically turn up the error_reporting level" Configurable logging and reporting is a feature, not a bug.
You bet it's a bug when only critical errors are reported by default. Errors in code aren't shown, and users don't realize that there's a problem in their code until it's being exploited.

"fopen_urls: By default you can include scripts hosted on other websites!" I'll agree, that should probably be off by default. But a developer has to be naive or dim to either use an URL include, or include a variable in the include directive (and thus introduce the possibility of a URL inclusion) without being damn sure what they're doing.
I don't think you can blame the developer for this. If they develop with magic_quotes on, or register_globals off, or error reporting >E_WARNING, they may not realize the variable in the include string is writeable, and they probably wouldn't realize you can include remote documents anyway.

"Input checking is difficult...Do you want htmlentities() or htmlspecialchars()?" Depends on what you want to do, now, doesn't it? Developers have to know what conditions they need their data to adhere to, and PHP gives them a variety of tools to make it fit those conditions. Feature, not a bug.
What about add_slashes() not escaping everything that mysql_escape() does? Or mysql_escape() not escaping everything that mysql_real_escape() does? What about 5 == "5 OR 1=1"? What about the ability to input arrays (and errors which should be shown when dealing with unexpected arrays aren't printed because of the default error reporting level)? These are bad ideas which make sanitizing input difficult.
It's easier to trip up badly in C (by commiting some memory buffer error) or Perl (by writing line noise code that you can't understand a week later) than PHP. But it's no longer fashionable to bash those languages.
I wouldn't use C for the web either, and Perl can be very clear. I agree that PHP gets a worse rep than it deserves; I like PHP, and understand that if bash or C was the language of the web they'd be just as bad, but they're not and PHP is.
PHP would be so much better if they fixed the security holes; one of the reasons it gets such a bad rep is because it lets newcomers make mistakes so easily, I'd like PHP to be recognized as the excellent language it is but these security problems aren't helping.

Apparently what you see as "problems", others see as features.
Some see pointers and no bounds checking as useful features, but that doesn't mean they're a good idea for security.

Re:Who's fault? Zend's (1)

jrockway (229604) | more than 7 years ago | (#17570276)

> Perl (by writing line noise code that you can't understand a week later)

What? PHP has even worse syntax. Everything requires parentheses @print(foo(@$bar[$this->baz()->something(array(1,2 ))->else()])). At that point, you might as well be using LISP. Not to mention that 90% of PHP's syntax is completely useless and has no reason for existing. (Why bother with dollar-signs in front of $variables when EVERYTHING IS THE SAME TYPE? Why bother with an OO model that uses interfaces when THERE IS NO TYPING IN THE LANGUAGE. etc.)

Anyway, most people that actually know how to program find Perl much more readable. If you're having trouble, maybe you should adjust the focus of your monitor.

Re:Who's fault? Zend's (4, Informative)

TheLink (130905) | more than 7 years ago | (#17570018)

Definitely Zend's fault!

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.

there's plenty of blame to go around (2)

larry bagina (561269) | more than 7 years ago | (#17568646)

almost every php book or tutorial I've seen does incredibly dumb and insecure things... creating sql queries by concatenating strings without escaping input data, not using htmlentities, using global variables... that's an sql inection or xss problem waiting to happen.

PHP makes it easy to do dumb things and harder to do the correct thing. There's a low barrier to entry, so many php "programmers" don't know what they're doing. (this also applies to javascript...).

Point of fact... (0)

Secret Rabbit (914973) | more than 7 years ago | (#17568672)

... no language is idiot proof nor can a language be idiot proof.

Secure programming can be mostly done by defining an extremely narrow band of valid input and strictly requiring said input... for everything. Which mostly doesn't happen from what I've seen.

Why does SQL injection work? Because of improper validation. Another cause of insecure code is because of a high level of complexity (usually needless complexity). Why does this happen? Because mentally challenged project managers (and up) make ridiculous schedules for the developers and as such, the developers are forced to rush. This leads to bad design, cutting corners, etc. There's clearly going to be security implications in there.

You might notice that the above doesn't make reference to any particular language. That's because such things are *independent of the language!!!*

From what I've seen, PHP pumps out "less secure" code not because of the language itself (i.e. the interpreter, etc), but because it is easy to learn. So, you have a bunch of graphic designers, etc that want to program the site themselves, so they learn PHP. Now how secure do you think that there code will be?

Languages don't currently hold it for you while you piss, nor should they.

Basically, "make it idiot-proof, and someone will make a better idiot."

This is real life, not nursery school. Take responsibility for your actions/knowledge or lack thereof, stop blaming the language, shut up and do you job properly!

Both are to blame. (0)

SkWaSH (562395) | more than 7 years ago | (#17568690)

I have been working as a full-time PHP developer for nearly 3 years now, and was a casual developer in the pre-PHP4 days. I will be the first to admit that I haven't always taken all of the necessary security precautions, but now I feel that I do pretty well in that area.

Just today I came across a huge flaw in the design of PHP as a language. I wrote some PHP4 code this past summer to encrypt credit card numbers and other sensitive data for secure storage. Since then we migrated the system to PHP5 and I was able to make use of the MUCH better implemented public/private/protected attributes of data members in classes to protect the key I was using for the encryption/decryption. I have been using ioncube to encode the PHP source to hide my key from prying eyes, but I discovered that the key is made visible by doing a simple print_r or var_dump on $GLOBALS.

I realize that the private/protected attributes aren't intended to keep data like this secure, but the point of this long post is to say that there isn't any way provided of securely keeping sensitive data secure.

So my opinion to the question asked is this: uneducated PHP developers cause most of the security problems in PHP applications, but the language itself could definitely use some extra security consideration.

Re:Both are to blame. (0)

Anonymous Coward | more than 7 years ago | (#17569874)

Your program obviously has to be able to read the key, otherwise there's no way to use it. Similarly, obfuscating your program doesn't help at all, because it has to get turned back into a form PHP can understand so it can be run, at which point the key you're concerned about will be in memory somewhere and can be pulled out.

Re:Both are to blame. (1)

socalian45678 (940808) | more than 7 years ago | (#17569916)

The private/protected thing is not a flaw in PHP! It is possibly a flaw in the english language that the word has different meanings in different contexts. Private and protected are about data hiding in sense of encapsulation, which helps maintain proper separation of concerns between datatypes. It has nothing to do with security. In C++, you can get around access modifiers using pointers or references. In Java and C# I believe that the knowledgeable coder can get around them by reflection. Most dynamic OO languages don't even bother with them. If you are executing untrusted code (such as eval'ing a user-supplied string containing, for example, print_r), all bets are off for security. Ioncube isn't even intended as a hacker-safe tool. It's meant to keep your customers coming back to you for changes, or to make sure that no one does cowboy coding on deployed servers.

PHP is no worse than C. (3, Funny)

Ant P. (974313) | more than 7 years ago | (#17568732)

C gives you enough rope to hang yourself with.
PHP gives you lego bricks. Most PHP users, for some inexplicable reason, try to eat them and choke.

Developer's Fault (1)

KermodeBear (738243) | more than 7 years ago | (#17568924)

I have been working with PHP for over six years at this point. I have worked with bad developers and good developers. The good developers write good, secure code. The bad developers write bad, insecure code.

This doesn't seem to change when the language changes, either.

There are simple fundamentals that good programmers follow that the bad ones do not; Correct error handling and reporting, data validation, etc., etc.

If it was the language's fault, or the fault of the tools, companies like Yahoo and Google would not be using it.

So old... (1)

ErGalvao (843384) | more than 7 years ago | (#17568944)

This whole thing about PHP being a non-secure language is so old that is getting really boring. There's no such thing as a bad programming language, there are bad developers.

You can write bad code in any language, it's your fault, your decision and yes, you should be held responsible for it.

PHP is an extremely easy language to begin with, so many developers begin their careers using it, therefore making bad applications. There are good Java coders and bad Java coders. There are good Ruby coders and bad Ruby coders. Why it's so surprising that there are bad PHP coders too?!

Where are the articles about GOOD PHP apps/programmers?! What I say is: There's a vice of calling PHP a less secure language. It's prejudice and misinformed. It's not good for the language, not good for the programmers and even worst for those who make this kind of statement.

Oh, and for those PHP features that are the source of many of the problems bad developers cause, PHP 6 will ship without the possibility of using register_globals, which is a very good thing.

both are at fault .. but let's fix PHP! (0)

Anonymous Coward | more than 7 years ago | (#17569020)

Okay. First of all I have been programming in PHP since PHP 3.x. I am currently working on medium to large public sites written in PHP. The first time I programmed in a high-level language was 15 years ago. In the IT world, this either means I'm an expert, or I'm a clueless idiot, depending on whether the person I'm talking to is an expert or an idiot. :-)

Anyway, I have no problem at all placing a lot of blame on PHP. Here are the major issues I have to deal with EVERY DAY:

1) NO HTML ESCAPING BY DEFAULT IN TEMPLATES! This is just asinine and inexcusable. When I insert text into a PHP template, I expect *exactly that text* to be displayed in the browser. If I have angle brackets, show the angle brackets in the browser, and so on. On those *few* occasions when I need to insert HTML into a template, I'm willing to use a different, longer, more-difficult-to-type character to string to turn off the escaping. But no, PHP decides that it will do the unsafe, uncommon thing by default, and if I want to escape, I have to use htmlentities() or some LONG function name like that. You could almost eliminate an entire class of errors just by changing this.

Think about it: you make a mistake with the current PHP behavior, you forget to escape.. what do you see? NOTHING DIFFERENT. (or maybe, you will see your app mentioned on Bugtraq someday ;-). If PHP escaped by default, and you made a mistake, and forgot to NOT escape, what would you see? ANGLE BRACKETS ALL OVER THE PLACE.

2) THERE ISN'T EVEN ONE LANGUAGE CALLED PHP: why? That ridiculous php.ini garbage. All my apps have to ship with a script to test about, hmm, 10-20 settings to make sure they are the same as I assumed when coding the app. Yes, people can change php.ini, but they shouldn't have to! Remove php.ini please, make it so this stuff has to be set at RUN TIME if people need to change it.

Languages should only be configurable from WITHIN THE LANGUAGE, in my opinion.

3) Need more convenience functions to clean form input: one thing I always to do with newbies is give them my library of functions that strip whitespace, normalize space, strip non-digits, strip invalid chars from emails, and other obvious stuff. I think PHP should have some of these BUILT-IN (so that it's taught to newbies and everybody knows its there and can be used in code examples without extra clutter, etc).

Yes, you can do this with regexps and stuff, but that's not the point, it needs to have some of it out of the box, and it needs to be shown in all PHP code examples.

For example, I'd like to be able to tell people to do things like this:

$email = strip_whitespace($_POST['email']);

(and of course it would be nice if the PHP folks cracked open a book on programming languages once in a while [exception handling without "always"/"ensure" blocks? huh????], but that's a whole 'nother ball of cheese.)

PHP??? (1)

drpimp (900837) | more than 7 years ago | (#17569062)

"Perfect Haven for Phishing"

So wrong and so right at the same time!

Speaking as a PHP Framework Developer (5, Interesting)

Foofoobar (318279) | more than 7 years ago | (#17569120)

I used to work with the Zend team and they seem determined o pander to the least common denominator of hobbiests and not allow the language to grow up. Things like nested classes and strongly types variab;es which should have been implemented in the latest version are strongly fought against. They things as well as other would help enforce good coding standards. But I have been told by the Zend developers themselves that they like to leave it up to the developer to code badly and to me that makes the language just as much to blame. I think the industry has established by now what are good programming habits and methodologies and what aren't.

PHP- making wrong things easy & right things h (1)

TheLink (130905) | more than 7 years ago | (#17570106)

It's not even that they leave it up to the developer to code badly. They make it easier to code badly than to code correctly[1].

Just using the infamous (mis)features that make PHP PHP, automatically make your code bad. e.g. magic_quotes, register_globals, addslashes etc.

PHP - making the wrong things easy, and the right things hard.

[1] http://ask.slashdot.org/comments.pl?sid=216482&cid =17570018 [slashdot.org]

Partially PHP's "fault" (1)

Jeian (409916) | more than 7 years ago | (#17569134)

... though the fault, IMO, is simply being a language that's easy to use.

I can write secure PHP because I started web-scripting in Perl, and had to do a lot of stuff by hand (and learn how to do it by looking at other people's code), and in that way learned security principles that superseded whatever I was actually writing.

No offense to PHP coders, but it's too easy for any idiot to learn the basics, call themself a "web developer", and never learn a thing about good coding practices.

Re:Partially PHP's "fault" (1)

tiocsti (160794) | more than 7 years ago | (#17569988)

*cough* pot. kettle. black. ever hear of cpan?

Like ruining screwheads with the wrong bit? (1)

SlappyBastard (961143) | more than 7 years ago | (#17569156)

The whole blame PHP or blame the programmer argument ultimately falls onto the programmer. If you use too small of a bit and end up stripping out a screwhead, should you blame Black & Decker for it? Of course not. Likewise, if you use PHP the wrong way, should you blame PHP for it?

Re:Like ruining screwheads with the wrong bit? (1)

nuzak (959558) | more than 7 years ago | (#17569312)

> If you use too small of a bit and end up stripping out a screwhead, should you blame Black & Decker for it?

If that's the only bit that comes in the set, yes. PHP could have deprecated its old single-string DB APIs. It didn't. People still use them, and sometimes they even take your credit card data with them.

You have to know a tool's limitations (1)

SlappyBastard (961143) | more than 7 years ago | (#17569458)

The greatest flaw to PHP is that it opens up more power than many of its users can handle. When you had to compile CGI binaries, it placed explicit limits on who could work on web apps. Now? The power that was once reserved for a handful of good programmers is opened up to all sorts of non-programmers and novice programmers.

What is needed is better education. An up-front warning to the non-programmers about what exactly it is they are getting themselves, their clients and their clients' customers into.

neither and both (2, Insightful)

JoeCommodore (567479) | more than 7 years ago | (#17569758)

The arguments:

PHP is secure as in it has the functionality to make secure sites.

PHP is insecure in that some of this is not implemented from the get go.

PHP is flexible as it does not force security on you - if for any reason you are running in an isolated environ or implementing something different attached to PHP.

By not being as strict in variable typing, etc. there are some things that can be done more directly in PHP then in other languages. Though it could cause hidden errors in good code as well.

There is stuff that can be fixed, Zend should get some of the hard housecleaning done (magic quotes, register globals, etc.) in a version # release (those who can't stick with 4 or 5 etc.) Though you then need to get the ISPs to upgrade and all the legacy scripts...

ASP, Java, Perl and Ruby people would like to see more stuff in their languages than in PHP (and will FUD PHP to promote thier cause good or bad).

I chose PHP because:
- it is on most webhosts and distro installers
- a lot of great code and/or projects are readily available in PHP.
- the language does everything I require and then some
- the syntax is VERY easy to read and understand - this includes my own code as well as learning from others.
- it is platform agnostic (no lock-in)
- it is not limited by licensing (if open source, which is ok for me) or vendor-control code restraints
- it works with many platform agnostic DBs also
- even the security issues are well documented and understandable and does teache you a lot more about web security than languages that just do it for you (or that you assume are secure).

So for me I know the drawbacks and I see the benefits, and the benefits are worth the extra effort.

In summary I see that it has worthy merits and also "warning labels", (such as this slashdot post illustrates) the devs will make up thier own mind on using it, get over it.

web developers using php (1)

chrisranjana.com (630682) | more than 7 years ago | (#17569792)

I would say the first class or lesson an aspiring programmer should attend will be BEST PROGRAMMING practises. He/she must delve deep into how to avoid security pitfalls while programming. I do believe that whether it is PHP or ASP or C# or Ruby on Rails.. If the developer updates both his knowledge and his software regularly and subscribe to websites like securityfocus etc Most of the applications which he creates will be secure.

Every Scripting Language Has Problems (2, Insightful)

Biffa (174808) | more than 7 years ago | (#17569810)

The first web scripting language that I did any sort of serious development with was Cold Fusion 1.0, late last century. It was simply amazing how much quicker the development of database-driven websites became. (Prior to that, I was compiling custom DLLs to load into IIS - or whatever it was called way back then.)

I very quickly made a whole series of small web applications to access our internal data - something that I later found out was called an "intranet".

Then, one day, when I was testing a form, I heavy fingered the single quote ' and the enter key on an input box and got some surprising results! The SQL statement got completely destroyed by including the quote in the input box. I actually thought this was fun, and typed in additional SQL to see if I could change the query. It was easy! I made the query do all kinds of weird things. This got me toying with forms that actually did inserts and adding random stuff to the query string and I realized how trivially easy it was to completely subvert all the smallish applications I had written. Thank the Lords of Kobol it was an internal site!

At any rate, I learned, in my safe sandbox, that securing a web application is not trivial nad is something you have to think about from the moment you sit down to code. I developed a bunch of functions to verify the existence of, escape, and validate every single piece of data that is ever passed from the UI to the database. You just have to do it, it's that simple.

Since those early days, I've done sites in Cold Fusion, ASP, JSP, PHP, Perl, WebCatalog and a couple of other oddballs, and I've always started by translating those functions to the new language, using the built-ins of the language when I could. You know what? All web scripting languages that are easy and powerful wind up being insecure in the hands of an inexperienced developer.

And let's be honest, if there was a secure and easy to use web scripting language, we'd all hate it because it tied our hands too much and made us do things a certain way. We, serious developers, love languages that let us do things the way we want to do them. Assembly developers feel confined by C, C++ developers feel confined by Java; HTML hand coders feel confined using Dreamweaver. So honestly, if they came out with SecurePHP, largely not backwards compatible for one thing, would anyone use it?

I know I'd WANT to, in theory, but would I? Would you?

Crowd Psychology (1)

KidSock (150684) | more than 7 years ago | (#17570142)

What all of the "PHP is insecure" claims refuse to recognise is that virtually all of the vulnerabilities reported would be no different had the application been written in some other language. PHP just has a huge installation base so of course there will be a corresponding increase in vulnerabilities. And lot's of newbies are not escaping things. Perhaps most damaging, high profile vulnerabilities in popular third party packages are giving PHP a bad name (e.g. phpBB). Language bashing is fun (what happened to good ol' Java bashing?). Programmers are bored. Take your pick. Yeah, occasionally there's a real problem but like that doesn't happen to Perl?

Anyway, the PHP devs sound like they want to make things better somehow. They have accepted that even if the security issues are user perception or crowd psychology (thanks to slashdot) that is a problem in itself and therefore something must be done regardless.

Oh, and that security guy Esser that left a few weeks ago is a nut-job. I've seen him posting on the PHP internals list. I'm not saying that he doesn't know what he's talking about but I find it very hard to trust anyone who is so undiplomatic. Also, apparently he's stared a "hardened php" site which to some could be construed as motive to make noise. I don't know, I'm not very well connected but that's just my instinct.
Load More Comments
Slashdot Account

Need an Account?

Forgot your password?

Don't worry, we never post anything without your permission.

Submission Text Formatting Tips

We support a small subset of HTML, namely these tags:

  • b
  • i
  • p
  • br
  • a
  • ol
  • ul
  • li
  • dl
  • dt
  • dd
  • em
  • strong
  • tt
  • blockquote
  • div
  • quote
  • ecode

"ecode" can be used for code snippets, for example:

<ecode>    while(1) { do_something(); } </ecode>
Create a Slashdot Account

Loading...