32

Suppose we have a config file with sensitive passwords. I'd like to version control the whole project, including the config file as well, but I don't want to share my passwords.
That could be good, if this config file:

database_password=secret
foo=bar

becomes

database_password=*
foo=bar

and the other users of the vcs could also set up the password on they own. To ignoring the file isn't a good approach, the developers should be aware, if the config file changes.

Example:

Local version:

database_password=own_secret
foo=bar

config file in vcs:

database_password=*
foo=bar

Then suddenly, the config file changes:

database_password=*
foo=bar
baz=foo

And the local version would become for each developer:

database_password=own_secret
foo=bar
baz=foo

This is my solution. How could I achieve this behaviour? How do you store your config files? Is there a way to do that, or should I hack something?

erenon
  • 17,952
  • 2
  • 56
  • 83
  • 6
    config files should not contain cleartext passwords.... – Mitch Wheat Dec 29 '09 at 14:33
  • 1
    in fact, it is preferable never to have any sort of password in a config file...unless it's a server held config, and even then... – Mitch Wheat Dec 29 '09 at 14:34
  • @Mitch: My PHP webapp (based on ZF) reads the DB credentials from plain text. Where should I store them? – erenon Dec 29 '09 at 14:39
  • 2
    do you mean programmatically and not pragmatically? –  Dec 29 '09 at 15:05
  • I could use svn's pre-commit hook to remove my passwords. Both it works only in one way. I need some kind of presync or preupdate hook. – erenon Dec 29 '09 at 16:00
  • -1 for storing plaintext passwords, which is plain-daft. See e.g. [here](http://security.stackexchange.com/a/17981/3272) – Tobias Kienzler Oct 09 '12 at 07:03
  • @TobiasKienzler: Please explain: how the hack would I "unhash" my sql password in the configuration file? – erenon Oct 10 '12 at 19:15
  • @erenon You wouldn't, you would compare the stored hash with the hash of your entered sql password. The authentication implementation does of course have to take care of that in such a way that the hash cannot be entered directly, i.e. it doesn't become the "password" – Tobias Kienzler Oct 10 '12 at 19:44
  • @erenon See e.g. here: [Storing Passwords - done right!](http://www.aspheute.com/english/20040105.asp) **edit** Actually, there's a relevant SO question, I hope it's helpful: [storing passwords in SQL Server](http://stackoverflow.com/q/876342/321973). Your question is basically good, I was a bit harsh in wording and voting, my apologies on that – Tobias Kienzler Oct 10 '12 at 20:11
  • Oh, and [The Definitive Guide To Forms based Website Authentication](http://stackoverflow.com/q/549/321973) – Tobias Kienzler Oct 10 '12 at 20:30
  • @TobiasKienzler: I need authentication in the other way around. (I'm not sure you understood this.) My application has to provide a password to an SQL server to create a connection, and not authenticate a user. (I know the concept of hashing really well, this won't work here) – erenon Oct 11 '12 at 10:03
  • @erenon m-/ Sorry, I got that completely wrong. Depending on your security demands, you might still want to consider encryption though... (Downvote undone) – Tobias Kienzler Oct 11 '12 at 19:08

9 Answers9

27

Instead of version-controlling the actual configuration file, you could put a template or defaults file in version control, and a script that would ask for DB information and credential to generate the real config file, which would be excluded from (i.e. ignored by) version control. On checkout, developers could run this script to get a working environment. This script could also be invoked as part of any installation process that your application uses.

Also see my answer to a similar question.

Community
  • 1
  • 1
Phil Miller
  • 32,214
  • 11
  • 62
  • 86
10

Not sure how your config is implemented, but having hierarchical overides is how I would handle this.

You have a main config that contains common config plus dummy username/password (or leave these out altogether). Each developer then creates a local override.config (or whatever) with their specific username/password. The main config goes under source control, the developer (or machine) local overrides do not.

I've done this in .NET but not PHP so I don't know how easy this would be I'm afraid.

Paolo
  • 20,855
  • 6
  • 38
  • 47
  • This seems very clever. To achieve this maybe I just have to subclass my frameworks config parser. – erenon Dec 29 '09 at 16:43
  • 1
    +1 This is exactly how we handle config files in almost all of our projects, with varying levels of hierarchies. – ZoogieZork Dec 29 '09 at 18:13
5

Create a local overrides file that contains the user specific info as PHP variables.

For instance create a file called local_overrides.php which contains the following:

$local_password = 'qUzaEAFK13uK2KHy';

Then in the file that includes your DB password do something like this

$overrides = 'local_overrides.php';

if (file_exists($overrides)) {
   #include_once($overrides);
   $db_password = $local_password;
} else {
   // perform appropriate action: set default? echo error message? log error?    
   $db_password = 'l1m1t3d!'
}

The local overrides file would never has to be seen by source control.

Robert Groves
  • 7,114
  • 5
  • 34
  • 49
3

Have a separate file with ONLY the secrets in, that isn't under version control?

Or ideally, do away with passwords entirely use openssh, or similar, and do public/private key authentication for each user.

James
  • 22,556
  • 11
  • 75
  • 125
2

What about a pre-commit hook to blank out sensitive fields? This assumes you're comfortable sending the file over the network in the first place, of course.

Update for the other end of the problem:
To handle updates, you'd either want to force a manual merge of the sensitive files, or modify the local build process to overwrite the sensitive lines with contents from a local/private/ignored file.

Andrew Coleson
  • 9,452
  • 7
  • 28
  • 30
  • I've just mentoined pre-commit hooks in my comment, but this technique works only in one way. Every developer should update their own password fields after every update&override. – erenon Dec 29 '09 at 16:45
1

My preferred answer to this was already mentioned here: check in a dummy file, generate the "real" file by copying the dummy file at runtime, and ignore the "real" file in your VCS.

I already answered a similar question, with a complete example how to do this in Visual Studio:
how to ignore files in kiln/mercurial using tortoise hg "that are part of the repository"

Community
  • 1
  • 1
Christian Specht
  • 33,837
  • 14
  • 123
  • 176
1

I'm used to make a txt file of it with the structure of the configfile. And after that I'll make a copy and change the extension and let my version control system ignore this file(s).

So when you make changes in the config file, just update the txt version of it. That's the only option I can think of which is logic as well (in my eyes)

Polichism
  • 224
  • 1
  • 7
0

In my projects I use a directory that holds these kinds of files but it's not uploaded to server, so my db config file is in that directory and it is configured for server where the project is placed. If someone changes config file he will change server config file and anyone updating revision will see changes in that file and will need to manually change his local config.

I don't see a way of doing it rather than that. If you find a different approach please share.

dfilkovi
  • 2,901
  • 5
  • 34
  • 49
  • I think it's better to keep your config file on ignore, and after modification, change password to *, commit it, then set ignore flag again, then change * back to password. – erenon Dec 29 '09 at 14:54
  • 1
    @erenon That seems like a lot of trouble. I would expect that developers would end up circumventing this or avoid committing regularly (committing the config file anyways.) Although its possible you could script the entire procedure. – Matthew Mar 29 '10 at 04:59
0

I had something similar to this although I don't know if it would work for you. I had a directory that contained files that contained passwords. This directory was not version controlled. The files were named after the applications which used them and in the config files, I 'sourced' the appropriate password file at the point it was needed. This would demand that your config parser can handle sourcing.

Noufal Ibrahim
  • 66,768
  • 11
  • 123
  • 160