• When a PHP application makes a database connection it of course generally needs to pass a login and password.
  • If you are using a single, minimum-permission login for my application, then the PHP needs to know that login and password somewhere.
  • What is the best way to secure that password? It seems like just writing it in the PHP code isn’t a good idea.

  • The usual solution is to move the password out of source-code into a configuration file.
  • Then leave administration and securing that configuration file up to your system administrators.
  • That way developers do not need to know anything about the production passwords, and there is no record of the password in your source-control.

  • If you’re hosting on someone else’s server and don’t have access outside your webroot,
  • you can always put your password and/or database connection in a file and then lock the file using a .htaccess:
[pastacode lang=”php” manual=”%3Cfiles%20mypasswdfile%3E%0Aorder%20allow%2Cdeny%0Adeny%20from%20all%0A%3C%2Ffiles%3E%0A” message=”php code” highlight=”” provider=”manual”/] [ad type=”banner”]

  • The most secure way is to not have the information specified in your PHP code at all.
  • If you’re using Apache that means to set the connection details in your httpd.conf or virtual hosts file. If you do that you can call mysql_connect() with no parameters, which means PHP will never ever output your information.
  • This is how you specify these values in those files:
[pastacode lang=”php” manual=”php_value%20mysql.default.user%20%20%20%20%20%20myusername%0Aphp_value%20mysql.default.password%20%20mypassword%0Aphp_value%20mysql.default.host%20%20%20%20%20%20server%0A” message=”php code” highlight=”” provider=”manual”/]
  • Then you open your mysql connection like this:
[pastacode lang=”php” manual=”%3C%3Fphp%0A%24db%20%3D%20mysqli_connect()%3B%0A%0A” message=”php code” highlight=”” provider=”manual”/]

Or like this:

[pastacode lang=”php” manual=”%3C%3Fphp%0A%24db%20%3D%20mysqli_connect(ini_get(%22mysql.default.user%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ini_get(%22mysql.default.password%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ini_get(%22mysql.default.host%22))%3B%0A” message=”php code” highlight=”” provider=”manual”/]

This solution is general, in that it is useful for both open and closed source applications.

  • Create an OS user for your application.
  • Create a (non-session) OS environment variable for that user, with the password.
  • Run the application as that user

Advantages:

  1. You won’t check your passwords into source control by accident, because you can’t
  2. You won’t accidentally screw up file permissions. Well, you might, but it won’t affect this.
  3. Can only be read by root or that user. Root can read all your files and encryption keys anyways.
  4. If you use encryption, how are you storing the key securely?
  5. Works x-platform
  6. Be sure to not pass the envvar to untrusted child processes

This method is suggested by Heroku, who are very successful.

[ad type=”banner”]

  • If it is possible to create the database connection in the same file where the credentials are stored.
  • Inline the credentials in the connect statement.
[pastacode lang=”php” manual=”%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mysql_connect(%22localhost%22%2C%20%22me%22%2C%20%22mypass%22)%3B%0A” message=”php code” highlight=”” provider=”manual”/]
  • Otherwise it is best to unset the credentials after the connect statement, because credentials that are not in memory, can’t be read from memory
[pastacode lang=”php” manual=”include(%22%2Foutside-webroot%2Fdb_settings.php%22)%3B%20%20%0Amysql_connect(%22localhost%22%2C%20%24db_user%2C%20%24db_pass)%3B%20%20%0Aunset%20(%24db_user%2C%20%24db_pass)%3B%20%0A” message=”php code” highlight=”” provider=”manual”/]

  • Best way is to not store the password at all!
  • For instance, if you’re on a Windows system, and connecting to SQL Server,you can use Integrated Authentication to connect to the database without a password, using the current process’s identity.
  • If you do need to connect with a password, first encrypt it, using strong encryption (e.g. using AES-256, and then protect the encryption key, or using asymmetric encryption and have the OS protect the cert), and then store it in a configuration file (outside of the web directory) with strong ACLs.

We have solved it in this way:

  1. Use memcache on server, with open connection from other password server.
  2. Save to memcache the password (or even all the password.php file encrypted) plus the decrypt key.
  3. The web site, calls the memcache key holding the password file passphrase and decrypt in memory all the passwords.
  4. The password server send a new encrypted password file every 5 minutes.
  5. If you using encrypted password.php on your project, you put an audit, that check if this file was touched externally – or viewed. When this happens, you automatically can clean the memory, as well as close the server for access.

  • An additional trick is to use a PHP separate configuration file that looks like that :
[pastacode lang=”php” manual=”%3C%3Fphp%20exit()%20%3F%3E%0A%0A%5B…%5D%0A%0APlain%20text%20data%20including%20password%0A%0A” message=”php code” highlight=”” provider=”manual”/]
  • This does not prevent you from setting access rules properly.
  • But in the case your web site is hacked, a “require” or an “include” will just exit the script at the first line so it’s even harder to get the data.
  • Nevertheless, do not ever let configuration files in a directory that can be accessed through the web.
  • You should have a “Web” folder containing your controler code, css, pictures and js. That’s all. Anything else goes in offline folders.
[ad type=”banner”]

Categorized in: