Handling Connection Strings

Published Thu, Dec 15 2005 15:44 | William

This issue comes up periodically in the newsgroups and I figured I'd address it so I can just point back to it in the future.  In essence, the question comes up "Should I use app/web.config files to store connection strings or should I hard code it in the application?"

Now there's two schools of thought, 1)  Hard code them and recompile whenever necessary b/c they shouldn't change  very option 2)  Store them in configuration files or hide them in the registry.  A former coworker of mine told me he worked with a guy who actually proposed storing it in the database but that has obvious shortcomings so I won't address it (and let me forewarn you, if you write me an email telling me that storing connectionstrings in a database isn't a bad idea, I'm not going to respond).

The only 'real' merit from my point of view in the #1 approach is security but I think that's dubious at best in a .NET scenario.  The argument I've heard is that it would take someone getting a hold of the .dll, knowing which dll and class contained the connection string and knowing how to use Reflector or read IL to get it out.  To me, this oozes of security through obscurity and is a bit lame.

The only 'real' criticism I've heard hard coding advocates make about using Web.config/app.config or the registry is that if someone has access to the web.config file, that they can see your connection string and change it.  This assumes that you haven't encrypted your connection string and if you aren't going to do that, then you probably deserve to be hacked.  So, let me go on record saying that I think it's dumb to have a plaintext connection string anywhere in your application, unless you have data that doesn't matter if it's compromised.  Similarly, make sure that unless you have a strong reason to do so, that you don't have any of your connection objects stored as public properties in your DALC classes.  A former coworker of mine told me of a case where they did everything right with respect to storing the connection string, but had the connection as a public property.  So all you needed to do was Debug.WriteLine(DalcClass.Connection.ConnectionString); and there it was plaiin as day.  Not much you can do about this though - although some db's have native support for encyrpted connection strings.

Another thing I hear brought up is that you don't have to change back ends very often so using a config file is useless.  Well, the first part is probably true.  But in most instances, you have at a minimum a test and production database.  Many of us have unit test databases, and staging dbs as well.  Having to recompile the application each time just so you can point to a different db seems kind of lame to me.

In short, I don't see any real benefit to hard coding your connection strings.  Most of the points I've heard for it seem to be based on the fact that somehow an evildoer would not be able to figure out which class your connection string was in.  More and more though, bad guys may not be outsiders and a lot of these obscurity based assumptions may not be valid.  Salt + Hash + Config seems like a pretty good approach to me.

Your thoughts?

Filed under:

Comments

# Scott C. Reynolds said on December 15, 2005 3:29 PM:

Actually I'm dealing with this delimma myself at this very second, since I got the notification of this post as I'm writing some data access plumbing for an app.

I vote app.config and encrypt. I think a) in .net if you don't encrypt and store it in the code it's just as good as being in plain text in an xml file. Anyone who has access to the config file can get to your assembly, and anyone that wants to use the information for nefarious purposes is going to be able to reflector it out.

Putting it in the assembly in the first place seems wrong...but I can't really say way. Dealing with SmartClient...I guess ClickOnce makes assembly deployment just as easy as changing a config file, so that's not really a good argument. For debugging, or for say...emergency failover to a temporary database for a few installed clients a recompile may not be feasable, which is where the config option is going to shine. Barring that scenario though...I'm thinking arguments for encrypting it in app.config vs encrypting it in the app itself are basically a wash.

My question though is this: web.config is trivial. It's in one place. But app.config could be on every machine in the enterprise....what's the best practice for encryption of that file prior to distribution? Google doesn't want to help me answer that question, it only wants to talk about web.config.

# skicow said on December 16, 2005 8:21 AM:

I use the DPAPI to encrypt my database connection strings and store them in web.config. I really like doing it this way because you will only get the strings decrypted properly if you use the DPAPI on the same server that it was encrypted on - and if the guy/girl breaking into your network can do that to decrypt you db connection string then you're already screwed.

# William said on December 16, 2005 8:46 AM:

Skicow, Scott - this is a typical exapmle of the non-web.config guys:
Even if it is downloaded because a misplaced security in the directory, than
it is in my opinion harder to get the connectionstring from the DLL than
from the config.sys

I am not so sure that every administrator set all rights in the correct way
(The main belongs to ASPNET, however the Bin should have other rights).

Downloading config.sys from an open bin directory is a piece of cake. If it
is in a dll, than your first chalenge is to know the name of it. Than you
have to know about ILS and than you can find (for not Net specials with a
lot of work) the configstring somewhere between that ILS code.

Therefore I have the idea that a connectionstring in a DLL on a webserver is
at least not less save than in a config.file.

If the situation is that you have to deploy almost exactly the same website
a lot of times than the config is of course a better approach, however not
for security reason but for deployment reason. However see what I wrote
about this before in this message thread.

----------
Whew

# Jeremy Brayton said on December 19, 2005 11:25 AM:

*Late*
2.0 includes that ConnectionString manager thingie. Since it does, why hard code anything? You could build your connection string by storing either random variable names or encrypt individual fields. Then you can just decrypt the fields, throw them at the connectionstring thing and watch it build it on the fly.

Of course I have no clue if this is feasable in ASP.NET, but I believe it should be. I don't see why anyone should store the entire string, as it can probably be Reflector'ed out. Storing the parameters themselves seems like a much better idea and easier to secure. Then again there's always Isolated storage if you wanna do all your processing on that one computer. That seems like a good option for ASP.NET as well.

# Sahil Malik said on December 21, 2005 12:57 AM:

Jeremy, that may be a bad idea as you would constantly regenerate potentially different connection strings.

IMO - store them as strings at one place. In 99% cases the config file is appropriate as when the app moves to production, the dba can take ownership.

I feel config + encrypt is probably the best solution around.

Scott, I had a situation where smartclients were involved. We still used config files and we'd update them as a part of the installation process. .NET makes it so much easier that you can run full fledged .NET code via the MSI during install. Also, we simply had a seed connstr that would hold the updated connstr in the database - that worked out fairly well for us.

# Kelly Martens said on December 21, 2005 11:32 AM:

Hello All,

I create an xml file, encrypt it (becomes "filename.xml.bin), decrypt it in the Windows app and then assign the string from the value in the XML key.

Works fine except there will be times when dealing with datasets in the designer that it will give me problems. Been pretty unhappy with how VS 2005 is handling this situation but it is probably because I have not figured it out completely.

By the way, if users need help using my method please contact me.

Thanks,
Kelly

Search

This Blog

Tags

Community

Archives

News

My other sites

Cool Stuff

Book Stuff

Security

ORM

Data Access

Funny Stuff

Compact Framework Stuff

Web Casts

My KnowledgeBase Articles

My MVP Profile

Design Patterns

Performance

Debugging

Remoting

My Fellow Authors

My Books

LINQ

Misc

Speech

Syndication

Email Notifications