PHP Application Insecurity - PHP or Devs Fault?
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?"
and addslashes. quick, which one is SQL secure?
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.
Want to improve your Karma? Instead of "Post Anonymously", try the "Post Humously" option.
Disclaimer, I am not a PHP developer!
... 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.
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!
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
My work here is dung.
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.
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.
http://outcampaign.org/
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.
How we know is more important than what we know.
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.
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
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.
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, 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...
The World Wide Web is dying. Soon, we shall have only the Internet.
Trick question.
None of the above, use bind variables instead.
Advanced users are users too!
I have to say, part of the quality of the "tutorials" and documentation provided by the language proponents should probably be taken into consideration.
.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.
For example, a while back I was reading the Microsoft training materials on
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.
Every php project I've seen uses raw mysql_* functions or a reinvent the wheel (only this time, it's lopsided).
Do you even lift?
These aren't the 'roids you're looking for.
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!
sex is better than war!
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
Google's Super Secret Search Algorithm: SELECT @search_results FROM internet WHERE @search_results = 'good'
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.
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.
I've audited quite a lot of PHP, written an article on PHP security from the hackers perspective, and done quite a lot of PHP development, and I've never come across an security problem that you could blame the developers for!
/. , and won't repeat myself here).
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 on
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.
// MD_Update(&m,buf,j);
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...).
Do you even lift?
These aren't the 'roids you're looking for.
... 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!
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.
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.
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.
Love sees no species.
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.
Er Galvão Abbott - IT Consultant and Developer
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. :-)
;-). 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.
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
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.)
"Perfect Haven for Phishing"
So wrong and so right at the same time!
-- Brought to you by Carl's JR
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 readab
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.
This is my sig. There are many like it but this one is mine.
... 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.
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?
I scream. You scream. I assume that means we're both acquainted with the problem. We proceed.
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.
I scream. You scream. I assume that means we're both acquainted with the problem. We proceed.
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 for PHP.)
GLaDOS for President 2016! "Well here we are again. It's always such a pleasure." -- GLaDOS, 2011
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
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.
"Enjoy what you're doing! If it becomes drudgery, you're doing it wrong!" - Jim Butterfield
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.
Chris ,
Php Programmers.
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?
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.
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 releaseTell that to the majority of shared hosting companies.
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].
d =17570018
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&ci
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.
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.
"If we knew what we were doing, it wouldn't be called research." - Einstein
Whilst I agree that the programmer needs to be responsible, the fact is that many people "programming" with PHP are _not_ programmers, or at the very least, are inexperienced programmers. So consequently, they write insecure applications.
So the argument that the developers of PHP could do more does seem valid! And the point that the previous poster made about lots of poorly coded functions, also seems valid.
You can do that now in a unpractical way. You can add a textNode, and set the content to the user output. A textNode will force everything to text, even &entities. ..where this text come from? you can do a ajax conexion, but is unpractical.
The problem here is
Anyway escaping in PHP/MYSQL is done with mysql_real_escape_string, and I dont think is bad.
-Woof woof woof!
Agree totally.
I've only recently got into using PHP myself. I am an experienced programmer, but it is surprisingly difficult to find a good solid way to properly escape MySQL statements. And before anyone asks, I'd write a function myself (like I've previously done with ASP/SQL server), but MySQL itself seems to allow.... lets say, at lot of "flexibility" in the encoding that can be used, and similarly, I couldn't easily find a complete description of this.
And sadly, googling for answers tends to pull up and awful lot of very badly coded/out of date examples.
Blame goes to both the programmers and the language. Ultimately, it's the programmer's fault if they write insecure code. Even in the very exceptional case where the language does not allow secure code to be written (which I think has been true of PHP a few times), the programmer can still be blamed for choosing to write code in the language. So the programmer is always at fault.
Having said that, the language certainly has an influence on what (security) bugs can be made or are likely to be made. As I've explained in some detail in my essay Better Languages for Better Software, many common vulnerability classes can be eliminated by providing the right language features and APIs. The typical vulnerabilities in PHP scripts (injection vulnerabilities) fall in that category. So PHP is definitely at fault, too.
Please correct me if I got my facts wrong.
I haven't looked into PDO yet, but MDB2 will work for your PHP4 code as well. I must add that MDB2 is not the golden egg either, its support for sequences is kind of lame when the db you're coding for natively supports them.
I do it differently, I move away from languages such as C *only* when necessary. Safety measures are indispensable, but there is such a thing as overdoing it. Motorcycle drivers should use helmets, but not truck drivers. Car seats should have safety belts, but not bar stools. And so on.
When I do a web page that will get input from the outside world I take care to use parameterized queries, but when I do a quick development I want an easy way to use the SQL code I have available. Too much "security" can become counterproductive. Converting legacy SQL code to parameters in function calls may introduce bugs that could be even more dangerous than SQL injection problems. It's the job of a competent programmer to choose wisely the tools and resources that he will use in each case, instead of branding highly productive languages, such as C or PHP, as "insecure" overall.
mysql_escape_string and mysql_real_escape_string should both work [...] 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.
Does anyone else not see a problem with this? Oh first we had addslashes but a lot of people complained, then we added mysql_escape_string but we decided it didn't work (for whatever reason) so now we have mysql_real_escape_string so people should be happy now. Oh and we have a magic_quotes variable you can set to automatically do this for you, but it might not be enabled on every instance of php.
And then we have:
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.
<sarcasm>Wow, these PHP developers really make it easy to do something simple like query a database! </sarcasm>
First I have a problem with lack of namespaces. Yes, you've heard it before but the above illustrates why it's a problem. If I instead had two libraries, mysql_escape and mysql_escape2 (bad names but bear with me), I could now have them use the same function names so I don't need to have mysql_escape_string and mysql_real_escape_string. To upgrade, I just change what library I include and I'm done. Having all these functions always accessible creates an inconsistent naming of functions.
I currently program in PHP as my real job.... I rarely use it in my personal web based projects preferring python or Perl (Possibly looking into Ruby at some point) because I've come to really dislike the language. However I also don't think it's as bad as some people make it out to be.
I'm by no means a PHP expert (I prefer Perl, but hey to each their own), but I've been helping my g/f learn PHP and have been trying to instill good coding practices, such as parameter binding in SQL. I found this to be a pain in the ass in PHP, so maybe I'm missing something.
Currently, I am only using MDB2, but to bind both integer and string parameters to an SQL query (ie. a user table with user_id and first_name), you have to actually pass an array describing the types of each argument, and then pass an array to the execute(). Making that first array of 'integer' and/or 'string' is the part I'm referring to being a pain in the ass, since I'm used to that being done automatically for me in Perl (or Java for that matter). Can PHP do that for me in any way? Maybe using another library?
In Perl, it's actually easier and clearer (IMHO) to use parameter binding in your queries, but in PHP with that extra array, this becomes extremely cumbersome for large tables. It's not that surprising to me a lot of developers end up embedding the parameters right in the string rather than doing it The Right Way because of this... which of course leaves them wide open for injection attacks....
though like I said, maybe I'm missing something here...
Security is primarily about education and not the language. I've been deploying public PHP applications for clients for years. In the early years problems were more abundant (registered globals, etc.), but in the later years (PHP5), the storm has calmed and common practices and patterns have been discussed, encouraged, and implemented so thoroughly that anyone making common mistakes these days simply hasn't educated themselves adequately.
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.
For he today that sheds his blood with me shall be my brother.
The language is largely at fault. Sure the PHP developer space is filled with 'ASP-level' programmers - but at the end of the day, there's only so much you can blame on the monkey's cutting code. PHP is an awful language, doesn't scale, doesn't promote anything remotely 'good', but still does the job. It isn't alone.
It isn't an entirely bad thing either. At the end of the day people need software that does something. Security is for the most part not a priority - and why should it be really? Only because of arseholes is it even be an issue.
But anyway, to cut it short - avoid PHP. The security issues are not even the start of how fucked a language it is. I'd much much rather code in C (C, not C++) than PHP any day (and yes, I've written production software in both). It doesn't have any more security issues - yet the ones it has are more obvious - it is orders of magnitude more scalable and performant, and it doesn't have any of the limitations.
_
\\/ are accustomed' - First Lensman
Let's not loose our focus. If you want to talk about guilt and who's responsible it's first of all the hackers and crackers. No matter what site they attack and what language it's writtten in. Website hackers are criminals and are the guilty. If my PHP website get's hacked (happend just a few weeks ago) it's the hackers fault. Not mine, not PHPs. As far as I'm concerned he should go to jail or pay for my expenses plus a hefty fee.
Apart from that it is, of course, my responsibility to keep my website safe, no matter what technology I use. PHP is a great piece of work and the best SSI solution available. It has it's pipeline covered with a set of OSS tools other solutions can only dream of and it has the largest amount of super-mature OSS webprojects available. All of which are, measured by their installbase, safer than anything else out there. Which proves that security in PHP is nothing special. You just have to compensate for PHPs upside (extreme easy of use) by doulbe checking it's downsides (enough leash to hang youself with). You have to apply basic brain functions when building critical PHP apps. Just like with any other technology. It's just that PHP ease of use lures novices into building larger apps that ignore security at first. Don't anyone tell me that his first C, Java, Whatever app was built with security and buffer overflow prevention in mind.
Blaming something on the language is just plain silly. If you don't like it, don't use it, period. It's not that there's a lack of them.
We suffer more in our imagination than in reality. - Seneca
someone smarter than me fork php already and drop the nasty backwards thinking bits (zend?).
I'm in the hole of the broadband donut.
A few years back (circa 2002), I whipped up a rapid application prototype with PHP while working off from some on-line tutorials and using Beginning Php 4 (Programmer to Programmer). I think the book and the tutorials were good a teaching the basic language features and syntax, but they taught me how to use PHP dangerously because they did not teach good practices. My application worked but never got out of the prototype/demo stage back then. Recently, I went back to it on my own time to try to clean it up, move it to PHP5, and make it deployable. I now cringe with horror at the extremely bad practices I was using back then. Granted, it was just a prototype, but I thought I was doing it "right" because I was following the examples in the book and the tutorials. I was doing stuff like accepting form data and passing it to the DB with out validation, outputing user submitted variables without checking for XSS, registering globals, etc, etc, etc.
So here is my point, all the tutorials, examples, and books that the neophytes are using to learn are _WRONG_. They are teaching _BAD_PRACTICES_. Because php is necessarily in a network environment (excluding the rarely used cli) and exposed to potential maliciousness, secure practices should be taught markedly at the beginning, not as an aside. So as part of teaching how to pass form parameters they should include validation code, even if they have to comment that section as "
I think PHP is a great language for its purpose, which is simple web-apps. Lots of the criticism about its brain-dead defaults is correct, but they can be overcome with good pratices by the application developer. PHP can be great, but it is typically taught wrong at the beginning and that just snowballs.
The editors and authors all the PHP books and tutorials out there need to make sure the new editions encasulate good practice at the beginning of the learning process.
That's a trick question. The correct answer is "bound parameters using PDO."
I do have the ability to write secure PHP code. And it takes much longer and much more effort than when I write secure perl, or python, or pike code. Because the language is poorly designed and has tons of misfeatures that promote security holes. Just because you *can* write secure PHP with enough time and effort, doesn't mean PHP is secure. The language should not go out of its way to make writing secure code more difficult.
Zend posts PHP tutorials and examples on their site that show how to write code with huge gaping security holes, and say "its ok because people shouldn't just copy our examples" when you point it out. When the developers of the language are giving newbies examples that are full of security holes, and don't even think that's bad, you know there's no hope.
"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."
First of all, its still VERY fasionable to bash C for being dangerous. There's a big difference though, C is not designed especially for web development. It was designed (decades ago!) as portable assembly. Assembly is dangerous, so portable assembly is too. PHP is a high level language designed for a task that requires alot of attention to security. It fails miserably to be suitable for this task. C succeeds very well at being portable assembly.
Second, as much as I dislike alot of perl's shortcuts, they don't tend to lead to security problems. Its definately easier to write secure perl than to write secure PHP. And perl and C both behave how you want when you are writing code in them. PHP behaves differently depending on how someone has messed with the php.ini. Have fun testing with all the variations of possible php.ini settings.
I agree. One of the developers gave me the excuse' it would be too hard for developers to understand' as the excuse for not using better programming methodologies. The developer would adapt and if it was too hard, how come other developers in other languages aren't having a problem picking it up. It's really discouraging since I'm developing an MVC framework for PHP and am beginning to hate the language because the developers in it can't grow up because the maintainers of the language don't want them to.
This is my sig. There are many like it but this one is mine.
I'd argue PHP is actually worse than C, since C at least behaves consistantly and doesn't depend on the settings in some .ini file to get reasonable behaviour. But even if PHP is "no worse than C", that's still incredibly bad for a language designed specifically for web development. C is dangerous because its portable assembly. PHP has no excuse for being dangerous, it was designed specifically for a security sensitive task in an era where exploits had already become common place. The idea of exploiting software was quite foreign in the early 70's when C was born.
It isn't just the programming language. It is what I refer to as the PHP mindset.
Not to pick on anyone in particular, but take a look at some popular open source projects (springing to mind are Joomla, mediawiki, mantis which each have some of the below problems).
They generally use only MySQL and only in ISAM format. There lies a whole set of issues around data integrity that shows that the developers are not thinking about quality and scalability.
They generally require installs in which the whole directory tree is owned by the web server user. The web server user owning any files at all creates a whole set of security problems.
They generally want you to supply and use the database root user instead of a user pre-created for the particular database application.
They generally put configuration items such as db passwords right there in the filesystem which is readable by the web server. Maybe using htaccess to help protect, but still right there.
Why has register_globals been left in? It should never have made it to php4, nevermind php5. What are the chances it actually gets removed for php6 like they said it would in php5?
Why does zend host tutorials that show how to do things in an insecure way, thus teaching people to write security nightmares?
Why don't the database modules use prepared statements or sprintf() syntax?
It shouldn't require attending conferences and buying magazines to write secure code. I write secure C code without having to do those things! I certainly never had to do anything like that for perl, or python, or pike, or ocaml, or...
Ah, yes, but a good craftsman doesn't blame the tool for a poor result, but that's probably because the good craftsman chooses good tools and refuses to work with poor tools.
Not knowing how to use a tool and choosing a poor tool are both faults of the craftsman.
I think that explains why so much php code is utter crap, the skilled developers stay far away from it, although some times some unlucky soul is forced to use php by his PHB and that some times leads to a working application.
-- To dream a dream is grand, but to live it is divine. -- Leto ][
... or 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... It doesnt, and it shouldnt. Your query should contain the wildcarding directive in it directly by appending to the string. Simply put:SELECT * FROM titles WHERE notes LIKE ? + '%'
Please don't gripe about prepared statements if you don't know what you're doing with them. Prepared statements are meant to ensure that when data is placed into the the string, it is formatted in such a way that it is always escaped and contains no directives or processing instructions themselves. You place the wildcard into the format string itself, thus you get controlled wildcarding based on data.
Regards,
-Steve Gray
Is there a situation where you would be unable to use a stored procedure to accomplish the same tasks?
Want to improve your Karma? Instead of "Post Anonymously", try the "Post Humously" option.
PHP application security. Do we blame php for the fact that it's a web language? On an enterprise application level, PHP doesn't have the highest penetration, but since the mass majority of web apps, from 20 liners to tens of thousands of complex open source ones, are done by independent developers or SMEs who require a stable, free, portable web language with low barrier to entry. Given the choice of LAMP on so many ISPs, PHP is the language of choice for the web. Since the web is MUCH less secure than any other type of development, it makes perfect sense that PHP is the least secure language out there, whether caused by the developers or the language itself, I'd say it's the least secure simply because it's the most ubiquitous web language out there. Your average one-off developer or small company doesn't have proper QA procedures. Enterprise level software is generally created in an environment that is more security-aware. Not the software, not the developers (necessarily), but the programming environment. As a PHP programmer for 6 years, I've learned my share of security lessons, and am aware of PHP's issues, but it's a language made from the beginning for the WEB (unlike java and much of .NET), and has inspired some of the most exciting web apps that exist. PHPBB was insecure, but so popular because virtually anyone could use it. Its popularity and insecurity both came from PHP. PHP still needs to work on the balance of accessibility v.s ease of programming and backwards compatibility, and with version 6, they seem to be doing just that.
---
PHP is the most popular web language. It operates in the least secure environment, and tends to be developed in non-QA'd environments more than other languages. Least secure language? Yeah, sure... that's it's nature! For web-coding in a QA'd environment by experienced programmers, the code is quick, efficient, portable, perfectly secure, and likely took less time to code than (almost) any other language.
My background is a combination of hobbyist and ComSci. I started in junior high with BASIC, and did C development for a time, got into infrastructure and now work exclusively with C#.
PHP is definately a hobbyist language. We need those, because there always needs to be a place for people to learn.
But I think what we in the industry need to do is a better job of explaining why things are bad, and why and *WHEN* you'd be better off moving to something different.
I think the mistake that I've seen PHP make is actually to try to focus on making PHP more of a grownup language, and less of a useful language. As such the more recent versions of the framework are not near as popular as version 4 was. What they risk by trying to be more like say Java or C#, is they risk having the hobbyists move on to something different. They will never compete with Java or C#, so why try? Keep your niche happy.
So I see your point, but maybe what you are really saying is that you personally have outgrown PHP and it's time to move on to something different.
And your comment really bothers me. There should be ONE function that safely escapes data for your database. Look at perl's DBI. You can ALWAYS rely on $dbh->quote() to do the right thing (though you should really use prepared statements and bind parameters).
Why does a supposedly simpler language make security so much harder?
Matt. Want XML + Apache + Stylesheets? Get AxKit.
From the looks of it, you're equating "prepared binded statements" with "one single hardcoded statement with parameters". That doesn't have to be the case. You should still use binds to pass the user-input to the SQL statement, but that doesn't prevent you from using: You can write your statement as varied as you want. Just ensure that user-input can't affect what you intend the statement to do (and binds are the safest, most future-proof way to do this).
SECOND : parameter binding through naming
If MySQL and/or PHP doesn't support this, then that's too bad. There is no reason why they can't support it. For example using Oracle and Perl's DBI package you can do: But if you "cant wait" for when this is available, you are apparently willing to use it. Then the only argument against using the (slightly more cumbersome, but no less secure) version that uses numbered placeholders is... laziness. I think.
THIRD : i want to see the final SQL
For debugging, that's a valid argument. However, if you set it all up correctly, you'll end up with EXACTLY the final SQL, minus the user-entered values. For debugging correctness of your SQL, this should be more than enough. If you are doing performance testing, having the "base" SQL handy and executing it manually by search-and-replacing the "?"s couldn't be easier.
Other than technical reasons (such as "the version of the database doesn't support it"), there is no good reason not to use bind variables when combining user-input with a SQL statement.
The answer:
mysqli prepared statements.
Slay a dragon... over lunch!
This variable should be SCRUBBED FOR CODE before I get it. That's the secure thing to do. If you want an unscrubbed version with php code in it, then I should as for it with an insecure variable like $_GET(code,insecure);
.01% of the time it's warranted. (How often do you really want code in your $_GET()?
Don't let the newbie make the newbie mistakes. Let the advanced user have what he needs the
Use prepared statements. Period. Full Stop.
It's reading about issues like this that make me love Hibernate, Struts and Tomcat. At least at work. ;-) It's all about the sensible security defaults and maintainability, neither of which are particularly common in PHP development. Seriously. All you PHP fanboys, I don't know if you're just scared of the learning curve or what, but the jump to J2EE is totally worth it for any serious application.
NO TOUCH MONKEY!
You can do everything you want with php5's native PDO (http://www.php.net/pdo). Any php prior to version 5 is trash.
:name
FIRST: Use PDO::query() if you don't want prepared statements.
SECOND: PDO supports naming. Replace the ? with
THIRD: You can probably do a dump on the statement object or something along those lines.
Which of the many open source libraries and tools compiled into PHP are "php"? That, in my opinion, is the security issue with PHP. The language isn't implicitly insecure. But the language links to a plethora of libraries that have different maintainers and different quality standards. If PHP is your sexual partner, you sleep with every library it sleeps with.