views:

120

answers:

3

I'm currently working on a website for my church's college group, and am started to get a little worried about the security of what I'm writing. For instance, I use this function:

function dbConnect() 
  {
  global $dbcon;

  $dbInfo['server'] = "localhost";
  $dbInfo['database'] = "users";
  $dbInfo['username'] = "root";
  $dbInfo['password'] = "password";

  $con = "mysql:host=" . $dbInfo['server'] . "; dbname=" . $dbInfo['database'];
  $dbcon = new PDO($con, $dbInfo['username'], $dbInfo['password']);
  $dbcon->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $error = $dbcon->errorInfo();

  if($error[0] != "") 
    {
    print "<p>DATABASE CONNECTION ERROR:</p>";
    print_r($error);
    }
  }

to connect to the database whenever I do a query of some sort. I always use the PDO prepared statements to prevent SQL injection from any user input, and I use htmlspecialchars to escape before outputting. My question is this: How do I protect my username and password for my database? I don't know if someone can view the source for my PHP files, but if they could, I can only imagine I would be hosed. What do I do?

+3  A: 

Ok, this needs some clarification. Some have suggested that you put sensitive data outside the document root. This has some merit but is more placebo than anything else in practicality.

You have to consider potential sources of problems.

  • Someone with shell access to the machine will compromise your database connection information regardless of where you put it. This can include both authorized users and those who exploit a vulnerability to get shell access (this has happened a lot);

  • If PHP is disabled or the Web server is fooled into thinking it is then there is the possibility that PHP files are served in raw form. Putting them outside the document root will protect you against this;

  • If someone somehow manages to write a PHP script to the document root, it's basically the same as someone having shell access so no measure will protect you.

Practically, if your Web server is compromised it is, the cases where your config files are outside the document root will protect you are fairly unlikely.

The main point of security with databases is to ensure that someone from the internet can't connect directly. This can be done with a firewall, binding the database to a private IP address or putting the database on a private server.

cletus
So I'm not being careless/insecure coding my database connection like this?
Cortopasta
@Cortopasta no, what you're doing is pretty standard.
cletus
Wow, this is so wrong. See Skilldrick's answer.
Draemon
This works if you control the host, but not in shared hosting. Can you give an example of a situation where your source is compromised inside the webroot if your web server is set up properly? And you're not storing your includes in a stupid way (.inc or anything else that is rendered as text).
Josh
@Josh - if it's shared hosting then you can't ensure that your web server is (or continues to be) set up properly.
Skilldrick
Its a paradox, since you don't often have access to things outside the webroot on shared hosting. More often people accidentally expose their svn tree (in which case you are screwed either way). On the content-type side, anybody who screws up an apache config that badly shouldn't be anywhere near a conf file. I'd also argue that anybody who has access to your source is likely to have access to the machine too, and if so, they can read files from outside the webroot anyway. Make sure to take other precautions (for example the mysql user, hashing and salting sensitive data in the db), too.
Josh
It's not a paradox, that's just a limitation of the shared hosting setup. There are all sorts of things that could potentially expose your source - apache bugs, php bugs, upgrades. If you're on a shared host you're not paying enough for top-notch admins. It is *far* more likely that your source is exposed than anything outside the webroot nevermind the whole machine.
Draemon
+3  A: 

There are precautions you can take. Create a mySQL user that is specific to what your application needs to be able to do. This can limit the amount of damage an attacker can do if he's compromised your username and password. For instance, allow the user to insert, update, select etc, but NOT drop, etc. Further, as cletus mentioned, the database should not be accessible to the outside. On shared hosting environment, this usually means the db can only be connected to from your www server or localhost.

Re: kalpaitch, don't pass your password around in some reversible hash. People should never see your source.

Josh
+4  A: 

You should put your database credentials in a file outside of the document root, so if something messes up and your PHP gets shown to users un-parsed, no-one will be able to see your password.

Have a look at this article on the subject:

The solution is simple. Place all sensitive data outside of your web server’s document root. Many experts now advocate placing most, if not all, of your php code outside of your web server’s document root. Since PHP is not limited by the same restrictions are you web server, you can make a directory on the same level as your document root and place all of your sensitive data and code there.

Skilldrick
Exactly. I wouldn't hire a PHP dev who didn't know this.
Draemon
are you saying I should put it in a seperate php file and include it in the page's file? Or something totally different?
Cortopasta
@Cortopasta: That's correct, but the file must be outside the document root. Strictly speaking you don't have to include it: You could read it as a config file, but traditionally it would just be another PHP file.
Draemon