[web] Protecting SQL passwords in PHP files

Started by
10 comments, last by Sander 16 years, 5 months ago
I was working on a small hobby project of mine, a blog-CMS-something-thingy which uses PHP and MySQL, and I just came to think about the issues of keeping your SQL password from prying eyes, more specifically in UNIX environments. The web PHP interpreter obviously needs to be able to read it, but on, for example, a shared hosting setup, you don't want just anybody to be able to read it. Now, this sounds simple at first. Simply stick the login credentials in separate config file to be included by all other PHP scripts that need database connectivity, change the file group ownership to the web server's group, set the permissions to 0640 and you're set. However, this only works if you have root permissions, since you can't assign the file group ownership to a group where you aren't a member, and if you so happen to be a member of the web server group (which is very unlikely), there's a fair chance that any other user on the same machine is too. I guess you could just set the file group ownership to the 'users' group and use permissions like 0604, which would protect the file from all other members of the 'users' group (but not from, say, breaches in other services or users who aren't members of 'users'), but this seems a bit hackish and some systems don't have a common group for all users. Perhaps this should have gone in the UNIX forum, but I wanted to hear about how you protect SQL passwords in PHP code. How do you people do it? Am I missing something really obvious and doing something really retarded here?
Advertisement
One option is of course to not use shared hosting.

Another is to enable base_opendir or whatever other restrictions exist in PHP - these are clumsy and there are potential ways around them, so it's not guaranteed.

One way which is quite nice is to have the database login / password passed in environment variables from the web server. This is straightforward to set up and means that other users can't read them at all, even with read access to your files (beware though: if they can gain write access, they can get them).

Create a per-virtual host configuration for Apache (make sure this file is not readable to any of the users) which sets the password in an environment variable (with SetEnv)

There are still ways; it is possible (but nontrivial) to read the contents of a process's memory out of /proc - where the passwords will be if you know how to find them. A shared hosting user can create a script to open a file in this directory and read it.

Cheers

Mark
Place secret file on server under your ownership. Execute a PHP script which creates a copy of that file under the sole ownership of the web server, and sets the most paranoid permissions possible (read-only, non-executable). Remove the original secret file.
Quote:Original post by markr
One option is of course to not use shared hosting.

Another is to enable base_opendir or whatever other restrictions exist in PHP - these are clumsy and there are potential ways around them, so it's not guaranteed.

One way which is quite nice is to have the database login / password passed in environment variables from the web server. This is straightforward to set up and means that other users can't read them at all, even with read access to your files (beware though: if they can gain write access, they can get them).

Create a per-virtual host configuration for Apache (make sure this file is not readable to any of the users) which sets the password in an environment variable (with SetEnv)

There are still ways; it is possible (but nontrivial) to read the contents of a process's memory out of /proc - where the passwords will be if you know how to find them. A shared hosting user can create a script to open a file in this directory and read it.

Cheers

Mark
That's pretty nifty. Seems a bit heavy to setup though.

Quote:Original post by ToohrVyk
Place secret file on server under your ownership. Execute a PHP script which creates a copy of that file under the sole ownership of the web server, and sets the most paranoid permissions possible (read-only, non-executable). Remove the original secret file.
That's so simple I don't know why I didn't think of that myself. Thanks for showing me the light.
Quote:Original post by ToohrVyk
Place secret file on server under your ownership. Execute a PHP script which creates a copy of that file under the sole ownership of the web server, and sets the most paranoid permissions possible (read-only, non-executable). Remove the original secret file.


Nice, but most prying eyes on a shared server have the same rights as the webserver. That's because most hacks are done by uploading a PHP Shell through a vulnerable website which is then accessed by a the browser, giving the hacker full shell access to the server under Apache's account.

<hr />
Sander Marechal<small>[Lone Wolves][Hearts for GNOME][E-mail][Forum FAQ]</small>

Quote:Original post by Sander
Nice, but most prying eyes on a shared server have the same rights as the webserver. That's because most hacks are done by uploading a PHP Shell through a vulnerable website which is then accessed by a the browser, giving the hacker full shell access to the server under Apache's account.


True. Completely isolating secrets from other users is a lost cause, because they have the same permissions as you have as far as script execution goes (and if they don't, problem solved), and script execution needs to access these secrets.

On DreamHost, apache runs under a different user (it's own) than PHP (which runs as my user). Thus, to protect secrets, I make a folder 'includes' and give only myself any permissions at all to it, and then I make the PHP files that need that information simply include the appropriate files from that folder.

Of course, this suffers the same problem as Sander mentioned - a php shell can still access the files just fine. The other half is to just write secure code =-)

Oh, and the third half is making sure there isn't anything that they can gain by taking all your information - properly salted hashes would be very difficult to use to steal passwords, for example, and frequent backups would mean that even if they empty your database, you didn't lose too much.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Quote:The other half is to just write secure code =-)


Problem is that you have no control over what other people are doing in their portion of a shared hosting server. Your neighbour may have installed some insecure PHP-Nuke script and allow the hacker to upload a webshell. Your files will still be toast because Apache can reach everywhere. If you want security, start by dumping shared hosting and going for at least a virtual dedicated host.

<hr />
Sander Marechal<small>[Lone Wolves][Hearts for GNOME][E-mail][Forum FAQ]</small>

Quote:Original post by Sander
Quote:The other half is to just write secure code =-)


Problem is that you have no control over what other people are doing in their portion of a shared hosting server. Your neighbour may have installed some insecure PHP-Nuke script and allow the hacker to upload a webshell. Your files will still be toast because Apache can reach everywhere. If you want security, start by dumping shared hosting and going for at least a virtual dedicated host.
Because PHP runs as my user, I can own all my files and not give the public (including the apache user) any access permissions at all to them. They also don't have list permissions inside most of my folders (or access folders that aren't web visible) so they'd have to know how I store my sites (which DreamHost allows you to customize) to access any files at all, but even then they can't get anything interesting - the source and config files are protected with full unix permissions so only my unix account has even read access. They'd have to actually escape the limitations of their unix user in order to do harm from another account, so my files are as secure as they would be on any unix machine that other people have access to.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Quote:Because PHP runs as my user, I can own all my files and not give the public (including the apache user) any access permissions at all to them.


That's a nice trick. Any idea how that's implemented? Can you see the Apache configuration for your virtual host?

<hr />
Sander Marechal<small>[Lone Wolves][Hearts for GNOME][E-mail][Forum FAQ]</small>

This topic is closed to new replies.

Advertisement