20

We have a development server and a live server with different database connection details (username, password, etc).

Currently we're storing BOTH the database connection details in a initial.php and one is selected if a DEFINE statement is present. We manually add that DEFINE statement on our live server.

Is this a safe approach? What are better / alternative approachs for managing DB connection security?

One consequence of this is that every developer can see the database connection details and that's a bit risky...

siliconpi
  • 8,105
  • 18
  • 69
  • 107
  • 1
    What OS, web-server and database are you using? This could be relevant. For example, using MS SQL Server and a web server running on a Windows machine, you could use Integrated Security so that the web server process itself would be authenticated to the database, and the PHP code wouldn't need a username and password. – Allison Lock May 04 '11 at 12:02
  • Does this answer your question? [How to secure database passwords in PHP?](https://stackoverflow.com/questions/97984/how-to-secure-database-passwords-in-php) – Nico Haase Oct 08 '21 at 16:11

5 Answers5

13

I use an .ini-file, which is then parsed via parse_ini_file(INI_FILENAME_HERE, true). This file isn't under version control (as are the php-/template-/whatever-files). So on every machine I create that file (.database.ini) for the respective database connection.

Example .ini-file for a MySQL-connection, using PDO:

[db_general]
driver = "mysql"
user = "USERNAME"
password = "PASSWORD"

; DSN
; see http://www.php.net/manual/en/pdo.drivers.php
[db_data_source_name]
host = "localhost"
port = 3306
dbname = "DATABASE_NAME"

; specify PDO-options, provide keys without PDO::
; see http://www.php.net/manual/en/pdo.drivers.php
[db_pdo_options]
MYSQL_ATTR_INIT_COMMAND = "SET NAMES utf8"

; specify more PDO-attributes, provide keys without PDO::
; see http://php.net/manual/en/pdo.setattribute.php
[db_pdo_attributes]
ATTR_CASE = "PDO::CASE_LOWER"
ATTR_ERRMODE = "PDO::ERRMODE_EXCEPTION"
ATTR_EMULATE_PREPARES = false

Since one can't use :: within .ini-file-keys, use constant('PDO::' . $iniKey) in your code to get the desired PDO-constants.

feeela
  • 29,399
  • 7
  • 59
  • 71
  • This doesn't solve the problem of visibility - but you can set a (single) default mysql database/users in the php.ini file – symcbean May 04 '11 at 12:30
  • @symcbean Maybe I didn't really understood the question, but I thought it was a general question on where to store db-settings. The addition "One consequence of this…" is answered by "This file isn't under version control". So every developer needs his/her own settings-file, plus the one on the live system. – feeela May 04 '11 at 12:38
2

I recently had to deal with this issue, and what I did was create two new database users. The first had no privileges at all, other than read privileges on tables in his own schema. The second had insert privileges to a "load" table I would be populating with my code.

The unprivileged user got a "credentials" table in his schema, which held the credentials and password of the insert user (along with some other parameters I needed for my app). So the code only contained the credentials for the unprivileged user, hard-coded and changed periodically, and at runtime it would look up the credentials it needed to do inserts. The lookup took place behind our firewall, between servers, so it wasn't something an outsider could eavesdrop on.

It wasn't developers I was worried about, it was outsiders and power users, who could theoretically gain access to the web server and peek at ini files. This way, only developers and DBAs could snoop (and we all know each other). Anyone else would have to figure out how to query the database, figure out what SQL to use, figure out how to run code... Not impossible, but certainly a gigantic multi-step pain in the butt and not worth it.

Pretty safe -- in theory, anyway...

Phil
  • 21
  • 1
1

Another approach would be to setup environment variables on the live and development machine and access them from the code... I don't know much php, but in python that would be:

import os
password = os.environ('DB_PASS')

This lets you distribute accounts and passwords as needed to developers and deployed servers. Depending on their permissions on that machine, developers could be prevented from having any access to the live password.

bjw
  • 2,046
  • 18
  • 33
0

Is kinda difficult to protect your application against the developers that are using it. My suggestions will be to load all passwords from a config file and create 2 separate environments: one for developing and one for the production server. Give full access to developers to the developing machine and when moving to the production server the application will feed itself with the production config which will be stored only on that machine and thus inaccessible to most developers. This type of security is more of a process and you have to define several steps, like who has access to the production machines and who is doing the publishing... etc.

Elzo Valugi
  • 27,240
  • 15
  • 95
  • 114
0

Is this a safe approach?

It depends on your definition of safe.

every developer can see the database connection details

AFAIK, other than using the default username/password/database in the php.ini file, that problem is pretty much unavoidable (and using the defaults mean they've automatically got access to the database anyway).

I guess you could use different include files encrypted using zend encoder with a function which returns database handles - and set up the scope and permissions for different files, but its tricky to isolate the PHP code the underlying data. Another approach would be to restrict everything to webservices and implement an extended permissions model in the webservice tier.

symcbean
  • 47,736
  • 6
  • 59
  • 94