tags:

views:

4738

answers:

16

Hi all,

When a PHP application makes a database connection it of course generally needs to pass a login and password. If I'm using a single, minimum-permission login for my application, then the PHP needs to know that login and password somewhere. What is the best way to secure that password? It seems like just writing it in the PHP code isn't a good idea.

A: 

MD5ing both the real password and the user submitted one, then comparing the two is a generally accepted way of avoiding storing plaintext passwords anywhere.

William Keller
That doesn't help him when he **needs* to get the plaintext password for the database to be able to connect.
Ah, I see, reading the question again, I see what he means.
William Keller
A: 

To be totally secure, you'll need to set up an ssl connection, otherwise anyone on your network can still sniff the password you type.

Charles Ma
+1  A: 

I think the OP means the database password.

Unless someone gains access to your server via FTP or SSH (in which case you're already buggered), I wouldn't worry about storing passwords in plaintext in PHP files. Most PHP applications I've seen do it that way, for example phpbb.

Ryan Bigg
+11  A: 

Store them in a file outside web root.

da5id
And also, as mentioned elsewhere, outside of source control.
Frank Farmer
Yes, very good point.
da5id
+26  A: 

Several period misread this as a question about how to store passwords in a database. That is wrong. It is about how to store the password that lets you get to the database.

The usual solution is to move the password out of source-code into a configuration file. Then leave administration and securing that configuration file up to your system administrators. That way developers do not need to know anything about the production passwords, and there is no record of the password in your source-control.

yep, I usually do DEFINE("DB_NAME","mydb"); etcit is also handy to define anything you'll be using on more then page, that you might want to change later
mrinject
Just saving the password in a config file is not much more secure. It needs to be properly protected, using strong ACLs and strong encryption with properly protected keys... See my post below.
AviD
I agree that the config needs to be properly protected. However knowing how to do that is the business of system administrators, not developers.I disagree on the value of strong encryption in this case. If you can't protect your config file, what makes you think you can protect your keys?
I prefer using a database account that is only allowed to acces the database from the web server. And then I don't bother encrypting the configuration, I just store it outside the web root.
gnud
@bentilly, that's where strong Key Management comes in, and this should definitely be the developer's responsibility, not the admin's - though the admins also have some tasks here too.
AviD
@bentilly so when you dont expose sensitive data theres no need for encryption at all? Not encrypting because you dont think anyone unprivileged would get access sounds odd for me - it makes the PIN on my VISA useless, since nobody should get access to it. edit: sorry, someone dug out an old thread
atamanroman
+2  A: 

Put the database password in a file, make it read-only to the user serving the files.

Unless you have some means of only allowing the php server process to access the database, this is pretty much all you can do.

Chris
+2  A: 

If you're talking about the database password, as opposed to the password coming from a browser, the standard practice seems to be to put the database password in a PHP config file on the server.

You just need to be sure that the php file containing the password has appropriate permissions on it. I.e. it should be readable only by the web server and by your user account.

Jason Wadsworth
A: 

Just putting it into a config file somewhere is the way it's usually done. Just make sure you A) disallow database access from any servers outside your network, B) take care not to accidentally show the password to users (in an error message, or through PHP files accidentally being served as HTML, etcetera.)

Marijn
+3  A: 

Your choices are kind of limited as as you say you need the password to access the database. One general approach is to store the username and password in a seperate configuration file rather than the main script. Then be sure to store that outside the main web tree. That was if there is a web configuration problem that leaves your php files being simply displayed as text rather than being executed you haven't exposed the password.

Other than that you are on the right lines with minimal access for the account being used. Add to that

  • Don't use the combination of username/password for anything else
  • Configure the database server to only accept connections from the web host for that user (localhost is even better if the DB is on the same machine) That way even if the credentials are exposed they are no use to anyone unless they have other access to the machine.
  • Obfuscate the password (even ROT13 will do) it won't put up much defense if some does get access to the file, but at least it will prevent casual viewing of it.

Peter

Vagnerr
A: 

If you are using PostgreSQL, then it looks in ~/.pgpass for passwords automatically. See the manual for more information.

Jim
+1  A: 

An additional trick is to use a PHP separate configuration file that looks like that :

<?php exit() ?>

[...]

Plain text data including password

This does not prevent you from setting access rules properly. But in the case your web site is hacked, a "require" or an "include" will just exit the script at the first line so it's even harder to get the data.

Nevertheless, do not ever let configuration files in a directory that can be accessed through the web. You should have a "Web" folder containing your controler code, css, pictures and js. That's all. Anything else goes in offline folders.

e-satis
but then how does the php script read the credentials stored in the file?
Christopher Mahan
You use fopen(), like for a regular text file.
e-satis
+9  A: 

For extremely secure systems we encrypt the database password in a configuration file (which itself is secured by the system administrator). On application/server startup the application then prompts the system administrator for the decryption key. The database password is then read from the config file, decrypted, and stored in memory for future use. Still not 100% secure since it is stored in memory decrypted, but you have to call it 'secure enough' at some point!

pdavis
+3  A: 

if it is possible to create the database connection in the same file where the credentials are stored. Inline the credentials in the connect statement.

mysql_connect("localhost", "me", "mypass");

Otherwise it is best to unset the credentials after the connect statement, because credentials that are not in memory, can't be read from memory ;)

include("/outside-webroot/db_settings.php");  
mysql_connect("localhost", $db_user, $db_pass);  
unset ($db_user, $db_pass);
Bob Fanger
+1  A: 

Storing something outside the webroot which can't be accessed from the web is a smart move. Then require() this file and use this with the mysql_connect . On my webhotel I have this file where all of my subdomain-folders are. So I've created a function that returns the password because I use multiple database-accounts.

function returnDatabasePassword($username) {
  $passwords = array(
    'db_username' => 'password',
    'db_username2' => 'anotherPassword'
  );
  return $passwords[$username];
}
Eikern
+2  A: 

Best way is to not store the password at all!
For instance, if you're on a Windows system, and connecting to SQL Server, you can use Integrated Authentication to connect to the database without a password, using the current process's identity.

If you do need to connect with a password, first encrypt it, using strong encryption (e.g. using AES-256, and then protect the encryption key, or using asymmetric encryption and have the OS protect the cert), and then store it in a configuration file (outside of the web directory) with strong ACLs.

AviD
+10  A: 

If you're hosting on someone else's server and don't have access outside your webroot, you can always put your password and/or database connection in a file and then lock the file using a .htaccess:

<files mypasswdfile>
order allow,deny
deny from all
</files>
sockleg
Thanks, that was exactly what I was looking for.
David Gladfelter
Useful, if it's truly secure, though it seems like a shell login would still have access.
Tchalvak
Definitely, but if someone has shell access, your entire account has been compromised anyway.
sockleg