Page 1 of 2
php - mysql password security
Posted: Mon Sep 26, 2005 8:31 am
by petterg
I'm quite new to php so bare with me if this is discussed before.
I'm about to make a website based on php/mysql on apache server. (linux)
To have a php/mysql driven website the mysql username / password has to be stored in the php code somewhere - in cleartext - and the file where it's stored has to be readable by apache (the webserver). (Am I right about this?)
I see this as a risky way of storing paswords. It means that everyone with access to put php files (or other scripts) readable by apache on the same server could make a script to output the source of my php files - including the password - to a website! What is the workaround for this?
I was thinking a way to go could be if passwords was stored in a separate file to be included by the script, and the includedfile was only readable to the owner of the script - not readable by the apache user. Could this in some way be posible using setuid on the php file, like done on programs, or sudo, or any other way?
Posted: Mon Sep 26, 2005 8:45 am
by Chris Corbyn
If you're on a shared server then there's a pretty good chance someone else could look at any of your files on that server. It depends on how well your host has set things up. I no longer used shared hosts as a result of several attacks on my scripts

Re: php - mysql password security
Posted: Mon Sep 26, 2005 10:27 am
by shiflett
petterg wrote:To have a php/mysql driven website the mysql username / password has to be stored in the php code somewhere - in cleartext - and the file where it's stored has to be readable by apache (the webserver). (Am I right about this?)
Read "What Can You Do?" near the end of this article:
http://shiflett.org/articles/security-corner-mar2004
Hope that helps.
Posted: Mon Sep 26, 2005 4:46 pm
by pickle
Long story short, you don't need to store your passwords as plain text. You can either hash them yourself (using md5, sha1 or some other method), or let MySQL hash it.
Essentially, the procedure goes like this:
1) User enters plain text password when they sign up
2) Script takes plain text password and stores hashed password in database
Then,
1) User logs in by typing their password
2) Login script hashes what user typed in and uses that hashed value in the query to check if credentials are correct.
You should know though, that some of the more common hashing libraries (md5 and sha1) have been broken, so the guarantee that they're not breakable isn't 100%. Using a stronger encryption like SHA 256 will work (although it to will inevitably be broken as well).
Posted: Mon Sep 26, 2005 4:51 pm
by petterg
It's a company server, but I'm the only person with root access. I can basicaly set it up however I want as long as it works for the company uses.
I know none of the current emploes have the knowledge to find passwords in my private php files, but now they're going to hire more ppl. I want to secure my scripts before all the new guys get login access.
Unless I'm missunderstanding the site Shiflett linked to - to store the mysqlpasswords in environment variables - everyone can just do a print_r($_SERVER) to see all passwords at once! At least when storing in a file they'll have to spend a few seconds to look for each of them.
Posted: Mon Sep 26, 2005 4:52 pm
by shiflett
pickle wrote:Long story short, you don't need to store your passwords as plain text.
It looks like you're misunderstanding the question.
If not, I'd like to see how you can use the hash of a password to connect to MySQL. :-)
Posted: Mon Sep 26, 2005 4:57 pm
by shiflett
petterg wrote:Unless I'm missunderstanding the site Shiflett linked to - to store the mysqlpasswords in environment variables - everyone can just do a print_r($_SERVER) to see all passwords at once! At least when storing in a file they'll have to spend a few seconds to look for each of them.
Are you wanting people to be able to log into MySQL but not know the access credentials? If so, that's quite a conundrum. :-)
Posted: Mon Sep 26, 2005 5:01 pm
by petterg
pickle wrote:1) User enters plain text password when they sign up
2) Script takes plain text password and stores hashed password in database
Well, that's the way to go if the site uses a login. There will still be a need to store the password to access the database where the hashed passwords are stored.
But when the site is mysql powered - to lookup data and save logs without having the user log in the password still needs to be stored somewhere.
Posted: Mon Sep 26, 2005 5:08 pm
by petterg
shiflett wrote:
Are you wanting people to be able to log into MySQL but not know the access credentials? If so, that's quite a conundrum. :-)
They don't need to login. The script should login to get it's data / write it's statistics.
As far as I know this is what is used for most sites, like online newspapers. (The admins have to login with their own passwords.
Posted: Mon Sep 26, 2005 5:16 pm
by shiflett
petterg wrote:They don't need to login. The script should login to get it's data / write it's statistics.
I'm just trying to make sure I understand the problem before trying to suggest a solution. As I'm understanding it, this sounds impossible.
It sounds to me like you have PHP developers who have read and write access to the code that connects to the database. Just to be clear, this means they can edit the file with mysql_connect(). This function takes the access credentials as arguments, yet you do not want these developers to be able to access this data. Does this sound right?
If so, then I think you'll find that this is impossible. You might look at one of these code obfuscator things, so that your developers have to include a file to connect to the database, and that file is very difficult to interpret. However, all you can really do is raise the bar - there's no way to hide this information from the person who uses it.
Hope that helps.
Posted: Mon Sep 26, 2005 6:15 pm
by petterg
With this code anyone with access to put a phpscript on the webserver can read out all files apache has readaccess to:
Code: Select all
$filename = "path/to/my/includefile.php";
$handler = fopen($filename, r);
$cont = fread($handle, filesize($filename));
$cont = str_replace("<?", "[PHP", $cont);
$cont = str_replace("?>", "PHP]", $cont);
echo "<textarea>$cont</textarea>
There are 4 kinds of users involded.
- The readers. They never login.
- The writers. They login to the mysql db to post/update the site
- The company employees. They have access to create php files on the webserver (including the codeexample above)
- Me. I have access to do whatever I want.
My goal is to give the readers access to read data without giving the employees access to get the mysql passwords that the script needs to use to read the data (using something similar to the posted code). As readers are loading different parts of the site there will be scripts storing statistics for which parts of the site is most popular (and some more). So the "hardcoded" password used for reading is not readonly. There are not much damage ppl can do with this password, but it's a prinsipal - it should not be that easy to find a password!
Did this clearify anything?
Edit: The phpfiles are owned by me:my_web_files and chmod = 640. Apache and me are the only users in the my_web_files group. The only way other users may access the code is through making apache run scripts.
Posted: Tue Sep 27, 2005 6:51 am
by sheila
It means that everyone with access to put php files (or other scripts) readable by apache on the same server could make a script to output the source of my php files - including the password - to a website!
Well, you either trust your fellow employees or you don't.
If you really don't trust them, then set up a separate development server for them to work on. When they complete scripts you install them on the live server.
Posted: Tue Sep 27, 2005 7:31 am
by Roja
sheila wrote:It means that everyone with access to put php files (or other scripts) readable by apache on the same server could make a script to output the source of my php files - including the password - to a website!
Well, you either trust your fellow employees or you don't.
If you really don't trust them, then set up a separate development server for them to work on. When they complete scripts you install them on the live server.
In many cases, they arent fellow employees: They are other customers of a large shared hosting company, in which case you have little or no trust of those individuals.
Most shared hosts use a variety of protections to ensure that one webspace cannot read from another. Whether its open_basedir, safe_mode, suExec, or more esoteric solutions (virtual hosting anyone?). The risk is definitely real, but its definitely a per-host issue.
If its honestly a fear on a given host, test it, and if it allows it, ask the provider what they suggest to prevent it.
Posted: Tue Sep 27, 2005 12:26 pm
by petterg
I trust the current emploees. But I don't trust those who are going to be hired soon.
Roja wrote:ask the provider what they suggest to prevent it.
Well, I kind of am the provider (as I'm the root user on the system). I need some help to prevent it!
Edit: I have the feeling there is a need to modify the php parser to make this work. Modify it so that ownership of files used by include and fopen has to be readable to the
owner of the running script, or the include / fopen fuctions should fail. As it is today it's only required to be readable to the apache user.
Posted: Tue Sep 27, 2005 12:32 pm
by feyd
Give them a blackbox class that does a socket connection to a second instance of the web server, that instance would then access to the actual data files (run under a different user). The live site can use the normal version of the blackbox script.