Forum Moderators: coopster
so I have lots of code like
mysql_connect(DB_SERVER, DB_USER, DB_PASSWORD);
mysql_query( $sql );
Now I need to define DB_USER etc somewhere.
But it would be quite nice if this information wasn't lying around for everyone to see.
My first approach was to create a 'config.php' file and place it outside my document root in directory called private in my user directory.
I could then include it in scripts with
require_once 'private/config.php'; (after suitably modifying the php include path) This at least meant that the file containing the password could never be accidentally served by the webserver if there was some kind of configuration mess up.
This seemed to work pretty well. However, there are two problems with that approach..
So I contacted the webhost and asked them what they suggested. They recommended running all my scripts that require DB access as CGI.
This involves copying them to the cgi-bin folder and adding a #!/local/bin/php line to the top of them.
Since CGI uses suexec to run as me (instead of nobody/nobody) it has access to files that only I can read so the password can stored safely.
I see the sense in this approach but I'm hesistant because..
But I usually put all sensitive information in a file, then I just include it. Provides better portability too. The file is placed, either outside the document root, or in a password protected folder.
$mysql_password = "mypass";
This way I can change information in just one place, and it will affect all scripts. :)
the file containing the password could never be accidentally served by the webserver if there was some kind of configuration mess up
I have often wondered about this. I put my password in a config.php file in the same folder as any .php file that may need it. Under what circumstances would the webserver serve the config.php without parsing it?
The only thing I could think of was if I removed the "AddType application/x-httpd-php .php" from the httpd.conf file. That would be a very easy problem to spot as all the .php pages on the site would be served without parsing.
So I've stopped worrying about it. For added security I like DrDoc's idea of putting it in a password-protected directory, so I might do that, thanks.
$MYDB_USER = "some_mysql_user";
$MYDB_PASS = "secret"; Then I issue a
require /somepath/notin/webroot/.db.inc The reason I used the . prefix is that usually ftp sessions don't show those files, so it may not be easily seen.
Another possible option is to use a local php.ini setting. You can set values in .htaccess that will specify what user and password to use when connecting to MySQL. (See Section 4 of the PHP manual).
Scott Geiger
Lately I've been thinking about using a homemade function to execute this. Even have gone so far as to begin planning a generic class which would contain several basic functions.
its a shared server so other users could read the file
seems to be the main problem. Do they have shell access or ftp? With shell there isn't much you could but if it is only via ftp you could do as Scott suggested and start the filename with a dot to keep them from viewing it in ftp.
I usually put all sensitive information in a file, then I just include it. Provides better portability too. The file is placed, either outside the document root
BCMG_Scot said:
my "solution" to this was to create a file outside of the web doc root
lorax said:
I have my dblogin info within a PHP file (not an .inc file) and located in a seperate dir at or above the level of the website root.
Yeah, yeah and yeah... but as I said, I can't do this because my webhost forces my home directory to only be readable by me (i.e. chmod 700) so PHP can't read any files in it. :(
The CGI version of PHP can, but it sucks for the reasons stated.
Any other ideas?
Under what circumstances would the webserver serve the config.php without parsing it?
Most likely situation would be that your host upgrades their installation of Apache (or whatever) and forgets to add the PHP handling back into the configuration file (so all php gets served as plain text).
On a shared server there is not much you can do short of the cgi method. That's the tradeoff for speed.
You may want to protect even further by having your include file like:
global.php:
<?
ConnectToDatabase();
function ConnectToDatabase () {
global $conn;
$user='xxx';
$pass='xxx';
$host='xxx';
$db='xxx';
$conn=mysql_connect($host,$user,$pass);
mysql_select_db($db,$conn);
}
?>
This still lets you handle your database connection in one place but has the added benifit of not having global variables containing your login information. So even if another user on the server included your file they could only call the function to connect to the database. Still not great but a little better. For them to see your information they'd have to fopen the file and read it in as raw text. A little more work.
daisho.
I'm not sure what FTP clients that you use but all the ones I use show dot files.
It has nothing to do with the FTP program... It depends on the setting in httpd.conf (or your local .htaccess for that matter).
grahamstewart, there are lots of options even if you can't put the file outside the document root. For example, name the file something funky (easterbunnybookshelf.php) and include() it.
It has nothing to do with the FTP program... It depends on the setting in httpd.conf (or your local .htaccess for that matter)
You are incorrect here DrDoc. Linux (and unix I beleive) shells/ls do not how files if they begin with a "." this has nothing to do with apache or httpd.conf.
Most FTP clients will show files that start with a ".".
daisho.
Other ideas:
1. Security by obscurity - name the include file something weird and if possible place it outside the docroot.
2. change your password often
3. don't make your password easy to guess
4. BACKUP, BACKUP, BACKUP!
and for the sysadmin - make sure the user does not have more permissions than it needs (i.e. shutdown privs)
Scott
Sorry to drag this one up again but I've been away for a bit and I'm still no closer to a solution.
lorax said:
Have you thought or/tried using some form of MD5 Hash as a way to 'hide' the dblogin information?
Umm.. yeah.. but MD% is one-way - there is no way to un-MD5 and you need to give the
mysql_connect function a plain text password. Even if I had some reversible encryption available I'd still have to store the password for that somewhere - so I'd just be moving the problem to another level. :(
figment88 said:
decent shared servers give you a directory above www root for precisely this reason
Can't switch hosts - we're tied because my client knows the reseller. There IS a directory above www root - but the problem is that it is only readable by MY account and not by the nobody/nobody account that PHP uses. (and if try and change these permissions they get changed back automatically by the hosting company). :(
jatar_k said:
if it is only via ftp you could do as Scott suggested and start the filename with a dot to keep them from viewing it in ftp
As daisho says, most ftp programs let you view . files (usually by selecting a menu option somewhere). Might stop a script kiddie but anyone with any experience at all will know to look for . files. :(
BCMG_Scott said:
Another option, but only if you own the server
If I owned the server it wouldn't be a problem at all, but I don't. Its a shared server with a hosting company. :(
DrDoc said:
For example, name the file something funky (easterbunnybookshelf.php) and include() it.
But whats the point if other people can read the scripts and see lines that say
include 'easterbunnybookshelf.php'; If I put the password in a php file could I setup .htaccess to prevent that file from ever being served externally? So it can only be include by other php scripts on the same server?
That way I could at least prevent public attacks and I'd only have to worry about 'internal' security (i.e. other sites using the same host).
Thats the best I can think of right now - other than giving up and using the messy cgi option.
Thanks for everyones help,
Graham
The webhost might decide to upgrade its version of Apache and forget to make the neccessary changes to the new httpd.conf file to activate PHP (thus causing all php to be served as plain text).
Might not sound very likely, but it does happen (I believe that it actually happened on this very forum before now).
But yeah.. my main concern is from other users of the server - which this approach will not address. :(
Still open to suggestions then...