Today I read an interesting article in O'Reilly's PHP Cookbook: Keeping Passwords Out of Your Site Files. When your passwords are in a hidden file (a file which can't normally be reached from the internet), it's much harder for unprivileged visitors to get your valuable credentials. In this example: username and password for your MySQL database.
How to do this:
First, create a file in /usr/local/apache/
(this folder can't be reached from the internet without SSH or FTP root permissions). For example, name this file database-passwords. The contents of this file is:
SetEnv DB_USER "username"
SetEnv DB_PASSWORD "password"
where "username" and "password" are your real username and password.
Add this line to the appropriate <VirtualHost> settings in /etc/apache2/apache2.conf:
Include /usr/local/apache/database-passwords
Restart Apache
Now, make a folder in your website root named mysql
add a file to this folder, named .htaccess (the contents of this file: deny from all), also add a file to the mysql folder named mysql-details.php, the contents of this file is:
<?php
$host = "127.0.0.1";
$user = $_SERVER['DB_USER'];
$password = $_SERVER['DB_PASSWORD'];
$dbname = "mydatabase";
$tablename = "mytable";
$db = mysql_connect($host, $user, $password) or die("no connection");
mysql_select_db($dbname,$db);
?>
where mydatabase and mytable are the real name for your database and table
Add this line to the php file in which you want to call the MySQL username and password:
include("mysql/mysql-details.php");
A big fat warning:
be sure no file exists in your website folder with the contents <?php phpinfo() ?> as with this command your credentials are revealed to the world (in the Apache Environment sector). Also, make sure not to expose the contents of $_SERVER in other ways, such as with the print_r() function. If you can prevent this, you're ready to go and you can be a bit more certain that your MySQL login credentials are safe from unprivileged eyes.
If you store your passwords in another environment variable, like $_CONFIG or whatever you prefer, you will not have the problem that you might accidentally expose your DB password with phpinfo() or print_r.
Posted by: Jelle | January 23, 2009 at 09:45 AM
And on second thoughts: in the above example the username and password are not immediately visible if someone can view the source of your mysql-details.php file, but if this person manages to get write access to the webserver directory it's fairly easy to change the mysql-details.php page in:
$user = $_SERVER['DB_USER'];
$password = $_SERVER['DB_PASSWORD'];
echo $user.'';
echo $password.'';
Posted by: Jelle | January 23, 2009 at 09:53 AM
Hi Jelle, thanks for your comments, highly appreciated ! I think it's a great idea to store your passwords in another environment variable like $_CONFIG, just to prevent that you might accidentally expose your DB password with phpinfo() or print_r. I think that when someone gets write access to the webserver directory, you're screwed anyway :-) I advice to store mysql-details.php in a different folder with a .htaccess file (deny from all) to add an extra (minor) layer of security, something which is not mentioned in PHP Cookbook. I'm looking forward to more advice from you!
Posted by: Mark | January 23, 2009 at 10:04 AM
Thanks for posting this ... I just wanted to mention that this does not work under PHP CLI ... I addressed this by including a php file outside of my web directory that was included on the php I'm running under CLI
Posted by: Ben | January 06, 2012 at 03:49 PM
like so:
if(!array_key_exists ('DBUSER',$_SERVER)){
include('c:/etc/dbpass.php');
}
Posted by: Ben | January 06, 2012 at 10:03 PM