views:

302

answers:

6

Hi everybody,

First time reader, first time poster (woo!)

So I've been implementing my login scripts for an informal website. Not likely to be compromised, but just to be safe, I'd like to ask if there's a security risk in having my MySQL database login stored in plaintext in the php code.

As far as I know, the code itself is parsed by Apache, so the end-user doesn't see it (just the output), which would mean it should be safe to keep... but I'd like a second opinion.

Summary: Accessing database through mysql_connect, mysql_select_db, mysql_query. Login info stored in local variables defined at each iteration of the script, and (I think) dumped once script terminates.

Security vulnerability?

A: 

Anybody who can login with root privileges on that web server (or possibly somewhat lower ones too) will be able to see your password -- but then, it's essentially impossible to defend against the super-user (wherever else you might keep your password, they could hack around and find it). Apart from this risk, you should be safe.

Edit: backups of the server could also be used (if unencrypted, or by somebody who can decrypt them) to recover your password if it's in-clear in your .php script. This possible attack might perhaps be mitigated (to great inconvenience/cost) by keeping the password on a different, secure location, and only sending it (securely) under highly restrictive circumstances. Is this the kind of attack you fear?

Alex Martelli
+6  A: 

That's very standard procedure for web applications that talk to a database.

I recommend taking read permissions away from the file for users other than the web server and yourself - if you have other users on your box that can spy on the file, they'll be able to access your mysql server.

Also, you should adjust the executable permission on the top directory as it'll prevent unauthorized users from even entering it.

Harden your mysql user's allowed host, so that only the boxes you need can connect to it.

Of course if your box is compromised and an attacker gains root access, there's little that will protect you.

Artem Russakovskii
+1 - It would also be a good idea to make sure the MySql user does not have privileges such as drop / grant etc.
karim79
+8  A: 

You could also consider moving the username/password combination to a seperate configuration file that lives outside the webroot. Make sure that place is not directly accessible from the webserver side.

That way, if for some reason the webserver decides not to execute PHP files anymore you don't lose the account information to the database server.

As an added bonus, if you use anything that makes a copy of the .php file (editors, SVN or whatever) in the webroot, you don't risk anyone getting around the .php execution.

ylebre
Truth. When i first started using linux, didn't notice Gedit made filename.ext~ and when i uploaded the folder, the ~ files would go with it. Then i could go to mysite.com/index.php~ and there it was in plain text
lyrae
@lyrae: I...good lord, thank you for pointing that out. I had no idea... O.o *runs and deletes*
David Thomas
If you absolutely must have the password in the PHP file, then atleast sha1 or md5 it.
Shoan
Shoan - MD5 and SHA-1 are one way functions - this will simply make the strings useless.
Artem Russakovskii
Excellent. Thank you very much for your insight!
Julian H. Lam
+1  A: 

You can add some additional layer of security by putting all your php files (except index.php of course) in a separate directory and protect them with a .htaccess file. This covers cases in which the php parser is not invoked and apache returns the files in clear text. One more thing that might be usefull: <?php defined('some_id_here') or die(); ?>. You can put this at the top of every php file except index.php (where you define some_id_here) so there is no direct access to your database-files.

merkuro
Has anyone ever seen a properly configured Apache instance NOT invoking the PHP parser.
fiXedd
OK you are right. I mean hypothetical things like this of course NEVER happen in real life, but I thought it was worth mentioning. Therefore a google search like "echo filetype:php" reveals nothing AND I don't find anything like this http://tppserver.mit.edu/index.php3 which leads me to http://tppserver.mit.edu/tpp_www.inc :o) haha
merkuro
I believe it happened to facebook in the recent past. http://www.phpdeveloper.org/news/8433
Shoan
Perfect. Some of my php files were coded as .inc, and were output as plaintext. Sequestering them in another folder was the perfect solution.
Julian H. Lam
@shoan - that was an apache config error, not a php failure.
Alister Bulman
+1  A: 

Not having the bulk of the code within the webroot, where it is possible, however unlikely, is just the first line of defence that can be taken.

Your database should also be secure even if the database user and password was published - by the simple expedient of only allowing a small number of source machines to connect to the database anyway.

Defence In Depth

<?php  // simplest /index.php, as the only .PHP file in the public-accessible webroot
require '../bootstrap.php';
Alister Bulman
Only works if your webhost is not moronic and forces you to put everything out in the open.
jmucchiello
... and so only if you give your money to a moronic webhosting company.
Alister Bulman
+1  A: 

I dont know how you connect to your MySQL database, but if you use PDO there is the possibility that the PDO constructor throws an exception. If you dont catch this exception the Zend Engine will show a backtrace by default and reveal your connection details!

It is just normal to store the connection creds inside a php file/variable or, in that case you use PDO, in the DSN (Data Source Name). I would even suggest you to put it inside a php file, because it will gets parsed and not send plain into the web...

One step to more safety is to put the login details outside the www-root or protect it with an .htaccess file (this would make it impossible to access the file via the webserver).

However on my server it is impossible to connect not from localhost. So i dont care if someone reads my login details (it is not the case of course.).

Tammo
Good point. I should configure my database to only accept local connections, since that's exactly how I have mine set up. Cheers!
Julian H. Lam