Solved

PHP Security question

Posted on 2014-10-04
25
154 Views
Last Modified: 2014-10-05
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?
0
Comment
Question by:elepil
  • 6
  • 6
  • 5
  • +3
25 Comments
 
LVL 82

Expert Comment

by:Dave Baldwin
ID: 40361809
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
0
 
LVL 51

Assisted Solution

by:Julian Hansen
Julian Hansen earned 100 total points
ID: 40361820
Only other way is to encrypt the password and then decrypt it before use. Not really a secure solution but will obscure from the casually prying eyes.

However even in a Java situation a determined person can reverse engineer the code and determine the password.

Open text passwords are always going to be an issue - which is why MS has integrated security. For me it is about securing the server and making sure that the DB creds have only the permissions needed to do what they do i.e. not GRANT ALL.

Even with encrypted source with a network analyser one can determine the password. The key point is that to get to the password one would need access to the server - and if they have that you probably have more problems to worry about than just the compromise of a db password.

After shellshock though this might become a very relevant question ....
0
 
LVL 7

Assisted Solution

by:Gauthier
Gauthier earned 100 total points
ID: 40361928
You can put a salt to the password in the environment variables.

That way at least the password will not be part of regular backups and reading the env alone will not give the pwd.

Just set the env var u_username outside of the code to  random value.

set the db password to the one generated by the code bellow
$pass = md5(getenv( 'u_' . $user ) . 'randomstring'));

Open in new window


Use the code bellow to connect to the db.
if you want better entropy/byte in you db password use something else than md5, but it need to be fast.
the random string and username better came from a config.php file which is not part of your cvs.
$user = 'username';
$pass = md5(getenv( 'u_' . $user ) . 'randomstring'));
$db = ... connect to the db
$user = 0;
$pass = 0;

Open in new window

0
 
LVL 27

Expert Comment

by:yodercm
ID: 40361933
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.
0
 
LVL 7

Expert Comment

by:Gauthier
ID: 40361963
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.
0
 
LVL 27

Expert Comment

by:yodercm
ID: 40362048
"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.
0
 
LVL 7

Expert Comment

by:Gauthier
ID: 40362111
@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.
0
 
LVL 27

Expert Comment

by:yodercm
ID: 40362125
@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.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 40362126
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!
http://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.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 40362132
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

0
 

Author Comment

by:elepil
ID: 40362144
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.
0
 
LVL 27

Expert Comment

by:yodercm
ID: 40362182
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.
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 108

Accepted Solution

by:
Ray Paseur earned 200 total points
ID: 40362220
If you're using a web hosting company, you are trusting them with everything you put on the server.  That includes your passwords, your data, your scripts, everything.  You are trusting them to keep the electricity on.  You are trusting them to keep backups.  You are trusting them to provide adequate connectivity and to protect the infrastructure from attack (electronic and physical).  Choose your web hosting company wisely.  I use and am pleased to recommend ChiHost.com.  I have also had good experiences with LiquidWeb and HostGator.  I have had poor experiences with GoDaddy and SiteGround. YMMV.

Edward Snowden was a trusted sysadmin.
0
 

Author Comment

by:elepil
ID: 40362223
Ray, may I ask what disappointed you with GoDaddy.com? They were actually the web host I was contemplating on.
0
 
LVL 108

Assisted Solution

by:Ray Paseur
Ray Paseur earned 200 total points
ID: 40362236
Sure.  I found repeated issues with database connectivity and their technical support was abysmal.  Other scripts on the server were making "pconnect()" or something similar and there were no more connections available.  My scripts were failing repeatedly in a deployed real estate site, and there was no excuse for the problem.  When I called them to ask for help I got put on hold for over an hour on a toll call, and got a run-around from an utterly incompetent tech support staff, making all kinds of excuses for not helping and saying things to the effect of, "We don't support PHP scripts."  No amount of asking, calling and pleading would get an appropriate and correct response.  Eventually we had to move to a more responsible hosting company at a cost of $1 more per month.  Would I have paid an extra $12/year to avoid this situation?  Gladly!

This is not to say that other hosting companies are perfect -- they are not.  But when I call ChiHost, I speak to knowledgeable staff who are in the room with the server and who can answer questions immediately. Same with LiquidWeb and HostGator.  They know what they are doing and they are committed to good customer support.  The differences in price for web hosting are inconsequential.  But an hour or two of my life, wasted, trying to get a minimum wage call-center employee to understand a technical problem, well, I just don't have time for that any more.
0
 
LVL 82

Assisted Solution

by:Dave Baldwin
Dave Baldwin earned 100 total points
ID: 40362263
I have yet to find hosting that is 'overstaffed' where the people who work there have time to go looking thru user's accounts to find things to break into.  Sure, there may be an occasional bad egg named Edward... but it is my impression that they log the actions of their admins and techs just because of the Edwards.  Godaddy, for example, hosts over 1 million web sites on 10,000 plus servers in several different locations.  Even their less than perfect 'tech support' does not have time to go looking thru all the accounts to find something to break into.  While Godaddy is the largest, their set up is similar to other large hosting companies.
0
 

Author Closing Comment

by:elepil
ID: 40362278
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.
0
 
LVL 27

Expert Comment

by:yodercm
ID: 40362281
Thanks for the "appreciation".  :(
0
 
LVL 82

Expert Comment

by:Dave Baldwin
ID: 40362287
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'.
0
 
LVL 7

Expert Comment

by:Gauthier
ID: 40362318
@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.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 40362319
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.
http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28531422.html#a40362126
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 40362329
@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!
0
 
LVL 7

Expert Comment

by:Gauthier
ID: 40362361
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.
0
 
LVL 82

Expert Comment

by:Dave Baldwin
ID: 40362400
You should know that many hosting companies do Not give you access "above the web root" and Godaddy is one of those.
0
 
LVL 7

Expert Comment

by:Gauthier
ID: 40362419
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...
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Introduction Many web sites contain image galleries; a common design for these galleries includes a page with a collection of thumbnail images.  You can click on each of the thumbnail images to see the larger version of the image.  This is easily i…
Deprecated and Headed for the Dustbin By now, you have probably heard that some PHP features, while convenient, can also cause PHP security problems.  This article discusses one of those, called register_globals.  It is a thing you do not want.  …
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to dynamically set the form action using jQuery.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now