Link to home
Start Free TrialLog in
Avatar of elepil
elepil

asked on

PHP Security question

When one writes code to connect to a database in PHP, is there a way to do this so that the database username and password are secure and unreadable? I came from Java, and I used to store the database login and password in the Java code, and after it got compiled, at least I knew it wasn't going to be as easy as viewing an ascii file.

Ideas, anyone?
Avatar of Dave Baldwin
Dave Baldwin
Flag of United States of America image

Not in 'regular' PHP.  IONCube and ZendGuard are the most common apps to encode your PHP source.  Neither one are free although some hosting companies do provide them.  This search will list some others: https://www.google.com/search?q=PHP+source+encryption
SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
PHP is server side code.  No user can see it.

If you are worried about the users of your system, no php is transmitted to anywhere they can see it.

The only people who could get your password from the php would be people who had direct access to the source code on your own server.
Avatar of Gauthier
Gauthier

PHP is server side code.  No user can see it.
Well that's what you wish. In practice, that's not the reality.

There are plenty of ways to exploit errors, coding oversight, php bugs, server bugs (shellshock...), configuration errors, source and backup leaks, and suddenly the code with the login and password is public.

Still the database server access is normally firewalled and only accessible from the php server. That's why we usually do not bother to secure it more than plain text in a php file. The server need to be really compromised for the login/password to be useful. And in that case, the database is compromised anyway. It remain a bad practice anyway.

And if for some reason you do not firewall your database server, it's a very bad practice. Since such a code leak is much more likely than a full server compromise.
"In reality", the end user cannot see the php, period.  

Unless your "code bug" is putting the password in displayable HTML, the end user will never be able to get it.

Certainly a hacker who can get into the server itself can get anything on the server, including your php code and the encryption you use for it.

I don't server hacking is anything a developer can prevent, that is a webhost/server problem.  As long as your server is secure, your passwords can safely be clear in the php code.
@yodercm You cannot be more wrong.

There are different levels of security problems ranging from Denial of Service, to information disclosure and the killer one the remote code execution.

Information disclosure bug are much more numerous than remote code execution one.
As a developer, you better plan for the critical information like passwords, email, credit card etc not to be readable through a regular information disclosure bug.

Server Hacking is something a PHP developer must keep in mind at all time.
Sloppy PHP codding along with account hijacking (weak or leaked password from webmaster PC) account for the vast majority of website hacks.

By the way a few, note on my solution:
1 My cleanup code $pass = 0 would not remove the password string from memory and it could still have been read by exploiting heartbleed...
2 Leaving around a phpinfo will expose your environment variables, exposing the db username.
@Gauthier:  LOL

Leaving around a phpinfo will expose ANYTHING.  

Normal php programming uses clear passwords right in the code and is perfectly safe as long as your server is safe.  If your server is not safe, NOTHING is safe.
The problem with dialogs about "security" is that they veer of into flame wars about absolutes, and usually there are no absolutes, but just degrees of security that are acceptable or unacceptable.  Here are some links to security-related topics.  First and most importantly, the PHP manual.  It has a section on Database Security that is required reading for PHP developers.
http://php.net/manual/en/security.php

Register Globals was a huge security hole in PHP.   It has mostly been closed, but it's important to be aware of why it was a security hole, so you do not accidentally do something like this in your own code.  I'm looking at you, extract() function!
https://www.experts-exchange.com/Programming/Languages/Scripting/PHP/A_7317-Register-Globals-a-bad-idea-from-day-one.html

Most security holes in PHP are not really in PHP -- they are mostly in code that is written by novice programmers.  Unfortunately there is a lot of dangerously insecure code posted all over the internet, and novice programmers sometimes copy this stuff and install it without understanding the consequences.  If you're not 100% sure of the security implications of a PHP code sample, do not use the PHP code sample, full stop.

Chris Shiflett has written extensively on PHP security, and while most of his work is a decade old, it's still good advice and a strong introduction to the important concepts.  He has a blog as well as this.
http://shiflett.org/books

This, too, is old.  But still very good advice today.
http://www.sitepoint.com/php-security-blunders/

The OWASP project keeps up-to-date on security issues.
https://www.owasp.org/index.php/Main_Page

There are some things you cannot handle in PHP, for example, DoS attacks.  And there are some things you can handle, up to a point.  If your PHP scripts are compromised and the PHP code is displayed for all the world to see, and your passwords are included in the code, you're toast.  So it would follow that a good way to store your passwords would be in a script that is outside of the WWW root directory.  By putting your connection credentials above the web root, you can use a PHP include() statement to bring the variables into your DB connection script and once connected, you can unset() the variables.  A directory structure might look like this:

account
|--www\
   |--js\
   |--css\
   |--index.php (etc).

Open in new window

A safe place to put your database credentials would be here:

account
|--credentials.php
|--www\
   |--js\
   |--css\
   |--index.php (etc).

Open in new window

You would put something like this in your index.php file:

require_once('../credentials.php');

Open in new window

The effect of this design is that credentials.php has no URL, so it's unlikely to suffer casual exposure, even if PHP fails and the scripts are exposed.

If you're on a shared server, consider whether the additional cost of a dedicated server is worth the additional security of knowing that nobody else can run code on your machine.

Ultimately your security efforts are like fire safes.  Fire safes are rated for time and temperature, and will allow the contents to survive without incineration for a while (presumably during this time you will be extinguishing the fire or changing your passwords, depending on the threat).  And it matters what you're trying to protect.  If you have bowling scores, or purchase histories, or medical records, or financial details, or nuclear launch codes the security measures are likely to be different.
Sidebar note: Here is a link to phpinfo() on my server.  What is the name of my database?  What credentials can you use to connect?  I'll leave this online for a while so you can see what's exposed and what's not exposed.
http://iconoun.com/q28531422.php
<?php phpinfo();

Open in new window

Avatar of elepil

ASKER

Actually, it wasn't just external users that concerned me but also the people at the web hosting company. Is my concern unwarranted on the latter, that they may have password overrides to my database anyway? I ask because I don't know the extent of the powers of adminstrators.
Yes.  At least some people at your webhost company would have access to everything on their system, including your code, your database, your data, and your firstborn child.   Well, maybe not the child.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of elepil

ASKER

Ray, may I ask what disappointed you with GoDaddy.com? They were actually the web host I was contemplating on.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of elepil

ASKER

I'm disappointed that PHP, having been around as long as it has, still does not have an adequate way to address this security vulnerability.

Nevertheless, I appreciate all your responses.
Thanks for the "appreciation".  :(
For what it's worth... from http://en.wikipedia.org/wiki/PHP 
As of January 2013, PHP was installed on more than 240 million websites (39% of those sampled) and 2.1 million web servers.
PHP is the most common server side programming language with about 80% of the 'market'.
@Ray Paseur
That's where I normally store my password/connection string outside the document root and in clear which is the accepted practice.
Would you consider splitting the credential between the environment and the php a bad practice?
Neither part alone would give you anything. Of course the code need to be adapted not to leak the username to the env.

Considering your server, the only oddity I found is that it happily serve the php.ini: http://iconoun.com/php.ini
I usually have a very restricted list of extension I allow apache to serve.
I'm disappointed that PHP, having been around as long as it has, still does not have an adequate way to address this security vulnerability.
PHP does have ways to address this, but you have to have a lot of "deep-background" knowledge to understand it.  Calling it a PHP problem is like saying that flight attendants should prevent all hijackings; it's very easy to think in those terms, but reality is not that simple.  Security is a full-time, four-year college major at the University of Maryland, and a masters degree at many major universities including CalTech, Carnegie-Mellon, MIT, Georgia Tech, Virginia Tech and others.  It's a constantly evolving field and you cannot learn enough about security, except to be dangerous, in a question and answer forum like E-E.  

For anyone coming upon this question in the future, the code snippets in this answer contain the current 2014 "best practices" for one tiny aspect of security: protecting the data base authentication credentials in small web sites.
https://www.experts-exchange.com/questions/28531422/PHP-Security-question.html?anchorAnswerId=40362126#a40362126
@Gauthier:  I'm not worried if anyone sees my php.ini, and I agree with you, in a deployed application, I would rewrite all of my URLs and limit access much more strictly than I do in this demonstration site.  But anything with a URL on my site is there for a purpose, so I'm happy to allow access.
splitting the credential between the environment and the php
You could, but I'm not sure that adds any value beyond the currently accepted practices.  I'd have to think about it more.  In the current practice, even if PHP fails and causes the web server to display the scripts all you'll see is something like this in the script.
require_once('../credentials.php');

Open in new window

So even if you knew where the data base server lived, and if you could somehow get a script into the server to try to connect, you would still not know the credentials.  Of course if you could get an unauthorized script into the server, the server and all of the sites hosted there would be in deep kimchi!
I was more thinking of someone leaving around some of the horrors which take any file name as argument, I've seen quite a few of those over the years...
neophytecode.php?file=/home/mysite/public_html/sample/snippet.txt

Still a correctly configured server should withstand that level of information disclosure without being hacked, but your credentials.php would be handed over no question asked. still not a risk to your database unless your database server is intentionally not firewalled.
You should know that many hosting companies do Not give you access "above the web root" and Godaddy is one of those.
Neither do some of them let you set environment variables or edit .htaccess files or write file from php...
Which is why we have some horrendous situation leading to saving ftp access code in clear in config file on the server, (Hello Joomla, wordpress,...) ftp code in clear in the webroot *THAT* is much more valuable than a db password.
No wonder so much plugin/Template leave glaring hole allowing to extract those code...