So our web server apps need to connect to the database, and some other apps have startup scripts that execute at boot time.

What's the best way to store the name/password for these applications, in terms of

  • security, e.g. perhaps we don't want sysadmins to know the database password
  • maintainability, e.g. making the configuration easy to change when the password changes, etc.

both windows and linux solutions appreciated!


Security or environmentally sensitive?

+2  A: 

plain text? If they're on your server, I would hope the server is secure enough not to allow unauthorised access. If people can access your config files on the server, something has gone wrong much earlier.

Following this strategy would result in missing an opportunity to build defence in depth.

clarification: in terms of security, maintainability (e.g. if the login needs to change, can I find it later, etc)

@lomax: perhaps I might not want everyone with access to the physical server (e.g. sysadmins) to see the password.


Mark Harrison

You can bake a symmetric encryption key into your binary, and have that binary read an encrypted username/password from a file on disk when it starts up.

However, this is not really much more than obfuscation, since your code is likely to be stored in some source repository somewhere.

I would suggest that you would be better served to control access to your servers both physically and over the network using a firewall and a private network bubble, and store the passwords in the clear (or base-64 encoded) on disk with permissions locked down to the run user for your web app.

You can also lock down the database server to only accept connections from your web app machines by IP.

Ultimately, your problem is that the key (your DB username/password pair) needs to be available for programmatic, unattended use by your web apps.

Nick Brosnahan
+4  A: 

I agree with lomaxx: if somebody is already on the server or has wide ranging access to it (like a sysadmin), the game is pretty much over. So the idea would be to use a server you trust that it is secure to the degree you want it to be. Specifically:

  • You need to trust the sysadmins
  • You need to trust anybody else who is running code on the same server (this is why shared hosting is a big no-no for me)

Beyond that, environment variables seem to be a popular choice for storing these types of credentials, because this means that access to the source only (for example by compromising the dev box) doesn't reveal it directly and also it can be nicely localized for each server (dev, test, etc).

It is quite conceivable that a flaw in the webserver could allow an attacker to make the server serve up a config file, but still not permit full access to the server. For this reason, and because it is generally a good idea to build defence in depth, you should not store sensitive data in a non-encrypted state.
+1  A: 

In most cases, I believe it is sufficient to obfuscate the password in a plain text file (eg. with base64). You cannot completely protect a stored password against a determined sysadmin with root access, so there's not really any need to try. Simple obfuscation, however, protects against accidentally revealing the password to a shoulder surfer.

A more complex alternative is to set up a dedicated secure password server that either:

  • provides a password decryption service
  • actually stores the passwords for use by other less secure servers

Depending on the network protocols used, this may not protect against a rogue sysadmin with tcpdump. And it probably won't protect against a determined sysadmin with a debugger, either. At that point, it might be time to look at something like Kerberos tickets.

Greg Hewgill
+9  A: 

The best way to secure your password is to stop using one. Use a trusted connection: How To: Connect to SQL Server Using Windows Authentication in ASP.NET 2.0. Then you have nothing to hide - publish your web.config and source to the world, they still can't hit your database.

If that won't work for you, use the built in configuration encryption system in ASP.NET.

Jon Galloway
+4  A: 

PostgreSQL offers a nice solution for this kind of situation in their documentation. Essentially, you use ssh to bridge a port on your machine to the PostgreSQL server port on the remote machine. This has three stages of authentication:

  1. Restrict access to the local port, such as only letting a particular user connect to it.
  2. Set up password-less connection to the PostgreSQL host with ssh as a particular user.
  3. Allow the user ssh connects as to have local access to PostgreSQL without a password.

This reduces the security to whether your user accounts are secured and your ssh configuration is sound, and you have no need of a password stored anywhere.

Edit: I should add that this will work with any database that listens to a TCP/IP port. It just happens to be described in PostgreSQL. And you will want iptables (or the equivalent off Linux) to do the port restrictions. See this.