9

For a dedicated server, is it better to store the connection string in web.config or machine.config? what's the advantages and disadvantages of each approach?

Thanks

Edit: I'm concerned about security here, so, the question is about which approach is more secure.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Waleed Eissa
  • 10,283
  • 16
  • 60
  • 82
  • In either location you ought to consider encrypting it (although if you're using trusted connections, I wouldn't worry that much). There's a rather handy tool for this now at http://somewebguy.wordpress.com/2009/07/16/encrypt-your-web-config-please/ – blowdart Jul 26 '09 at 10:52
  • Link in comment above dead; now at http://hugoware.net/blog/encrypt-your-web-config-please – Chris J May 02 '12 at 13:30

7 Answers7

10

I would always go with web.config on the grounds that that is where everyone would expect it to be. There is no point in giving the person that has to maintain the web site any more difficulty by storing connection strings in an unusual place.

ADDITIONAL

Based on the additional information that the OP is interested in the security aspect, rather than and general reason I've added the following.

I still wouldn't store connection strings in the machine.config. If you do that any .NET application running on the machine has access to your connection strings.

web.config is a protected file. IIS won't serve it up by default unless you do something to misconfigure it.

Colin Mackay
  • 18,736
  • 7
  • 61
  • 88
  • I agree. Keep it simple. And not just for others, for yourself, too. – serialhobbyist Jul 26 '09 at 10:10
  • Actually I'm going to maintain the site myself so this is not a problem. – Waleed Eissa Jul 26 '09 at 10:10
  • 2
    My recommendation makes no mention of who the maintainer is. Even if it is you, my recommendation still stands. Keep things simple. 6 months down the line you might have forgotten. – Colin Mackay Jul 26 '09 at 10:17
  • I won't forget, promise :) .. seriously, the point in the question is to know which approach is more secure and why. It seems to me machine.config can be a little more secure than web.config. Security is my real concern here. – Waleed Eissa Jul 26 '09 at 10:23
  • Then you may wish to edit your question to reflect that you are more interested in the security aspect. – Colin Mackay Jul 26 '09 at 10:29
  • It's not so much IIS/ASP.NET serving it up (although there's a possibility there could be a bug) that should be the worry, but your own code. Scripts to serve files that don't take relative paths into account are a wonderful way to get access to web.config. – blowdart Jul 26 '09 at 11:16
  • @blowdart, interesting point. This seems like a good reason to consider machine.config – Waleed Eissa Jul 26 '09 at 12:21
  • @Waleed: everything I've read here indicates *do not* use machine.config. It's utterly non-standard – gbn Jul 26 '09 at 13:34
  • I've also changed the id the ASPNET process is hosted by to a domain account. Then use integrated security and give that account the absolute minimum security it needs to get the work done (granting it dbadm is bad). – Jeff Siver Jul 26 '09 at 21:08
  • @Jeff S, actually I'm using MySQL, so no integrated security with that – Waleed Eissa Jul 28 '09 at 09:22
  • Is there anyway it can be stored in IIS? so that all website can access to database ( I only have one webserver with 10 websites and I dont want programmers to make modifications to web.config, or even if they do, I dont want them so see it) – Akash Kava Oct 19 '12 at 17:53
  • If the programmers have access to the servers at a level to allow them to see the web.config then what is the real issue of them being able to see/modify it? It seems to me you either need to set up an operations team to maintain the web.config or trust the developers to have access to the server. – Colin Mackay Oct 25 '12 at 19:48
10

I prefer to keep my connection strings in the machine.config.

My connection strings are different between the DEV, QA and PROD environments and if I kept them in the web.config I couldn’t safely blow away my target directory and copy up the new code. Or I would have to remember to deploy everything but the web.config, this creates issues when other parts of the web.config change.

It depends on your situation, but when it gets a little complicated the risk of having the wrong connection string in the wrong environment is just too great. We have actually had situations where testing was hitting the wrong databases because the connection string was inadvertently moved. Machine.config is used for machine specific items - thus the name. It never gets moved from machine to machine.

So in my machine.config I have multiple connection strings like blogConnString, forumConnString, projectxConnString, etc. I don’t consider this mixing setting for different sites, I consider it keeping machine level setting in the maching.config.

You were worried about security, I think once they are on the box they are equally secured. But if the connection string is in the web.config it usually ends up in source control, developer’s desks, in backup files, in install plans, deployment sets, etc. This makes the web.config way less secure to me.

Finally, another approach is to have it in a totally different config file (say WebEnvironment.confg), that is then referenced in your web.config. This file would sit in a directory that is not physically under your web site, but is virtually under your site. More details are HERE.

JBrooks
  • 9,901
  • 2
  • 28
  • 32
  • 1
    Sorry, but I totally disagree with this. Machine configuration goes in machine.config, not application configuration. Database connection strings are application specific, not machine specific. – OJ. Feb 06 '13 at 00:17
  • If you install Windows now you will get a default connection string in machine.config - LocalSqlServer. It is the machine configuration value for the local SQL Express. I have the machine configuration for my blog, my main website, etc. As a developer, it just makes it so easy. – JBrooks Feb 06 '13 at 04:32
  • To each there own. But I don't see "MS do it so it's ok" as a good justification. I've lost count of the terrible code examples that were on MSDN's website. Just because they created it, it doesn't mean that their suggestions on how to use it are the best. I also don't dig the focus on the "making life easy for the developer", but again that's personal preference. It's not about me, it's all about the software. – OJ. Feb 06 '13 at 08:48
  • 1
    I agree with JBrooks. Config settings that change between environments are a huge pain and it's much easier to manage environments when all of those are in the machine.config instead of the individual ones. It makes sense to me - on our staging server, I always want to point to servicetest.example.com and on production, I always want to point at service.example.com. Why would I want to manually maintain these settings for every application and also have them duplicated across tens of projects? – lukevp Jan 28 '16 at 22:32
  • @lukevp This is exactly what [web.config transforms](https://msdn.microsoft.com/library/dd465318(v=vs.100).aspx) are for. – CraigTP Jan 30 '16 at 11:12
  • 1
    @CraigTP So would you put sensitive information such as production connection strings (including password) into the release transform file in your source code repository where every developer has access to production login details? – hofnarwillie Feb 15 '16 at 23:43
  • @hofnarwillie FWIW, I actually would do this as I (and the organisation I work for) trusts the developers with such information. – CraigTP Feb 16 '16 at 10:12
  • 2
    @CraigTP, that's very nice. The company I work for has 300 developers (several of whom are contractor staff members who usually come and go within weeks), so it's not as simple as trusting everyone, as ideal as that may be. It would be irresponsible to your clients and their users' security. In the UK you would be in breach of the Data Protection Act (https://ico.org.uk/for-organisations/guide-to-data-protection/principle-7-security/) – hofnarwillie Feb 16 '16 at 21:25
5

I, personally, would never store my connection strings in my machine.config file, only ever in the web.config.

You say it's a dedicated server, but is this server dedicated to a single web application?
If not, you've now got a single file (machine.config) that's effectively sharing configuration data for multiple (probably un-related) web applications. Depending upon the number of those applications, and if you ever needed to move them to another server, using the machine.config could get very messy.

Even if the server is dedicated to a single web application, you'll probably be performing your development and testing on other machines. Since the machine.config is not normally a file that's included within the file-set of a ASP.NET web application project, you will probably have to go out of your way to deploy the machine.config to each of the various dev/test/production machines, and ensure that other (non-connection string) related configuration within them is correct for that machine.

Using the web.config to store database connection strings makes perfectly logical sense and is entirely expected by almost all ASP.NET developers, even if you have multiple applications that will use the exact same database on the exact same database server. Keeping this configuration in the web.config of each application allows each of those applications to be more self-contained and not reliant upon some other "outside" file.

I generally view the machine.config and something that the framework itself uses, and it belongs on a machine and is specific to that machine. I very rarely go in and touch it myself. I view the web.config as a file that's part and parcel of your web application project and "moves around" with that project as it moves and is deployed to different machines.

Also, don't forget that a lot of what's defined in the machine.config can be "overridden" on a per-application basis by redefining certain configuration elements within a specific application's web.config file.

Of course, there are a few valid reasons to editing/changing your machine.config file (such as multiple web servers in a web farm will probably need things like encryption/decryption keys within the machine.config to be synchronised), however, I don't believe database connection strings are one of those valid reasons.

CraigTP
  • 44,143
  • 8
  • 72
  • 99
  • Thanks for your detailed answer, it's a single web application by the way. – Waleed Eissa Jul 26 '09 at 10:35
  • Craig - I understand your point but I think you're missing the reality of maintaining large sets of applications that use web or app config. We have 25+ projects on some of our servers that all contain the same database connection string. We are going to have to manually update all connection strings in all projects in order to move our DB server to a new hostname. Whereas if they were in the machine config, we could change them in a single place. – lukevp Jan 28 '16 at 22:36
  • @lukevp For your given situation, which is somewhat unusual, I can understand wishing to store the connection string in the machine.config file to avoid repeating the exact same connection string in 25 different web.config files. I would suggest, though, that most people who have 25 applications on the same server will likely have many different connection strings, largely unique to each application. – CraigTP Jan 30 '16 at 11:11
3

If security is your primary concern, concentrate on locking down the database and user permissions. The security difference between web/machine .config is minimal. Colin's answer is correct. I'd have voted up or commented there but I don't have the moxie yet!

Jerry
  • 41
  • 2
  • Indeed - Security is a multi-layered beast. You should do your best to be locking down the bits below the surface as well as what is at the surface just to be sure. – Colin Mackay Jul 26 '09 at 11:35
1

There are a lot of good points, here. JBrooks's environment is closest to mine, but in the end, I disagree with putting connection strings in Machine.config.

I agree with OJ but not for the reason he cites, here. I would point out, as JBrooks said, connection strings will very likely use different credentials in development and production environments. Our intranet development databases, for instance, all have the same set of simple credentials while our production databases each have different credentials with complex passwords. So there are very good reasons for not putting your connection strings in the Web/App.config file but rather in a file local to the target server. I like the registry, myself, but I know that's not at all supported. Clearly, the Machine.config file is there to provide a solution.

No, I agree with OJ because Machine.config resides in the .Net framework and could be changed by Microsoft. But Microsoft knows nothing of the connectionStrings.config file on our production servers. This file is loaded by Web/App.config files with:

<connectionStrings configSource="path\to\connectionStrings.config"/>

blowdart made the point about encryption--always a good idea. But in the end, the only way to fully protect your database credentials is to change them periodically.

Community
  • 1
  • 1
sthames42
  • 888
  • 8
  • 19
0

security wise you could look into storing your connection strings in there own encrypted .config file that your web.config file would have a reference to.

MakkyNZ
  • 2,215
  • 5
  • 33
  • 53
  • 1
    You can encrypts just sections of the web.config. You don't have to create a whole new file. – Colin Mackay Jul 26 '09 at 10:41
  • 1
    i usually find it easier to manage if they are in a seperate file. especially if you have loads of connection strings. – MakkyNZ Jul 26 '09 at 11:09
0

all good points. In my environment, databases are shared so storing in a web.config forces redundancy. We use standard SQL databases here that everyone accesses. A separate config file is preferred. This allows for standardizing, security and the elimination of a need to change the web.config when an app is deployed.

Clem
  • 69
  • 1
  • 8