Protecting Sections of your Web.Config File

I recently got a couple of e-mails from people asking why I was storing unencrypted data in my web.config files for applications as the ones used in my N-Layer design examples.

The main reason is: I don't have much to hide. First of all, the web.config doesn't contain a lot of sensitive information. For example, I use Integrated Security in my database connections, so I don't have a need for clear text passwords. Secondly, the config files are stored on my machine in a safe way as only the Administrators group and the accounts used by the web server can access them. Finally, IIS and ASP.NET work together to block users from downloading the web.config file. (To see what I mean, try downloading this file: http://imar.spaanjaars.com/web.config. The file really exists on disk, but you get a 404 Not Found error nonetheless.)

But of course, your mileage may vary. Maybe you're afraid your client changes things they shouldn't change in the web.config file. Or maybe some of your co-workers can access the server through FTP to update the site but you don't want them to be able to change the settings. Or maybe you're afraid an employee of your ISP can read your sensitive data when your site is hosted in a shared hosting environment. In those cases, it's good to know it's very easy to encrypt sections of the web.config file.

Encrypting and Decrypting Config Sections

Encrypting and decrypting your configuration sections can be done using command line tools (as explained in the article How To: Encrypt Configuration Sections in ASP.NET 2.0 Using DPAPI ) but also through the .NET API. All you need is a few lines of code:

C#
Configuration myConfig = WebConfigurationManager.OpenWebConfiguration("/");
ConfigurationSection mySection = myConfig.GetSection("appSettings");
mySection.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
myConfig.Save();

VB.NET
Dim myConfig As Configuration = WebConfigurationManager.OpenWebConfiguration("/")
Dim mySection As ConfigurationSection = myConfig.GetSection("appSettings")
mySection.SectionInformation.ProtectSection("DataProtectionConfigurationProvider")
myConfig.Save()

This code opens the configuration at the root of the web site (indicated by "/" in the call to OpenWebConfiguration), gets a reference to the appSettings element and then encrypts the data using the DataProtectionConfigurationProvider. In order to save the changes to disk, you need to call Save(). You can use the same technique to encrypt other (but not all) configuration sections, like <connectionStrings />.

Decrypting is almost identical: instead of calling ProtectSection you call UnprotectSection, like this:

C#
Configuration myConfig = WebConfigurationManager.OpenWebConfiguration("/");
ConfigurationSection mySection = myConfig.GetSection("appSettings");
mySection.SectionInformation.UnprotectSection();
myConfig.Save();

VB.NET
Dim myConfig As Configuration = WebConfigurationManager.OpenWebConfiguration("/")
Dim mySection As ConfigurationSection = myConfig.GetSection("appSettings")
mySection.SectionInformation.UnprotectSection()
myConfig.Save()

Things to Watch Out For

This code uses a key to encrypt and decrypt data *local* to the machine where the code runs. That means you'll need to run it on the final destination: the web server where the appSettings section is used. If you encrypt the data on your development machine and then upload the encrypted config file to your web server, you'll get a run-time error when ASP.NET tries to decrypt the data again.

Additionally, the account used by this code (typically the Network Service account on Windows Server versions and Vista and ASPNET on Windows XP) needs read and write permissions to the root folder. This is not the case by default, so you need to grant these permissions to the appropriate account before you run this code. Typically, you want to revert back to read-only access again once you're done encrypting to close the security hole.

If you don't have your site running on / (that is, the Virtual Path property on the web site's Properties dialog in VWD is set to something other than / or you're running your site configured as a Virtual Directory in IIS) but you run the site on something like /WebSite1 instead, you need to change the call to OpenWebConfiguration like this:

WebConfigurationManager.OpenWebConfiguration("/WebSite1")

However, if you run this on a Windows Vista machine, you may get the following error:

System.InvalidOperationException: Failed to map the path '/'.

The error is caused by a security issue: you need to run Visual Studio and the built-in web server under the context of an administrator account. To fix this issue, close Visual Studio, right-click the Microsoft Visual Studio 2008 item on the start menu and choose Run as administrator.

References

This post is not meant to be a guide to encrypting files. It merely serves as an answer to those asking me about encrypting files in my web applications. For more details about encrypting files see the following references:

Downloads


Where to Next?

Wonder where to go next? You can read existing comments below or you can post a comment yourself on this article .


Consider making a donation
Please consider making a donation using PayPal. Your donation helps me to pay the bills so I can keep running Imar.Spaanjaars.Com, providing fresh content as often as possible.



Feedback by Other Visitors of Imar.Spaanjaars.Com

On Tuesday, April 07, 2009 5:32:21 AM Ruchit S. said:
Hi Imaar,

I guess you will also require to mention the ProtectionProvider in your config file. We used to do this during an Installation by calling our on Install method in the Installer class of our application. There we used to mention the DPAPI as our default ProtectionProvider. I do not see that in your code or is it not mandatory just ?


Thanks.
Ruchit S.
http://ruchitsurati.net

On Tuesday, April 07, 2009 6:06:58 AM Imar Spaanjaars said:
Hi Ruchit,

It wasn't required when I wrote this article. The download that comes with this article should work as advertised without it.

Cheers,

Imar
On Tuesday, April 07, 2009 12:04:49 PM Ben said:
The code doesn't work for me.

I guess defining DataProtectionConfigurationProvider is mandatory.
On Tuesday, April 07, 2009 5:34:46 PM Imar Spaanjaars said:
Hi Ben,

What version of .NET are you using? And which of the two samples?

I just tested it on my machine (running .NET 3.5) and the C# example works fine. There's a small issue in the VB version. Rather than getting myConfig.Sections(19) you should use myConfig.GetSection("appSettings"), just as in the Decrypt handler.

Once I fixed that, the VB version works for me as well.

Cheers,

Imar
On Friday, July 10, 2009 8:12:15 PM Craig said:
Imar,

In Visual studio you application works, but when I try to publish it. (i.e. make a virtual directory)

Everything appears to work, but it does not encrypt the web.config....Seems like a permissions issue.

Any help?
On Friday, July 10, 2009 8:53:24 PM craig said:
Got it... I need 2 things....First to get the correct path and second to put FULL CONTROL over the root folder. (Read and Write wasn't enough).

Dim myConfig As Configuration = WebConfigurationManager.OpenWebConfiguration("/V2")
On Wednesday, February 10, 2010 10:16:20 PM Mike said:
Thank you for an excellent article.  The sample to download was key to my understanding!
On Thursday, November 18, 2010 9:21:54 AM Rey said:
Well done,Thank you for an excellent article

Talk Back! Comment on Imar.Spaanjaars.Com

I am interested in what you have to say about this article. Feel free to post any comments, remarks or questions you may have about this article. The Talk Back feature is not meant for technical questions that are not directly related to this article. So, a post like "Hey, can you tell me how I can upload files to a MySQL database in PHP?" is likely to be removed. Also spam and unrealistic job offers will be deleted immediately.

When you post a comment, you have to provide your name and the comment. Your e-mail address is optional and you only need to provide it if you want me to contact you. It will not be displayed along with your comment. I got sick and tired of the comment spam I was receiving, so I have protected this page with a simple calculation exercise. This means that if you want to leave a comment, you'll need to complete the calculation before you hit the Post Comment button.

If you want to object to a comment made by another visitor, be sure to contact me and I'll look into it ASAP. Don't forget to mention the page link, or the QuickDocId of the document.

For more information about the Talk Back feature, check out this news item.