How to automatize Web.config Connection String Encryption on your ASP.NET Web projects

Published:
I'm sure this is not a silver bullet for many developers out there, but I've found it really useful and I think it's a good idea to share it with the whole EE community.

Surely you all know that usually connection strings are stated on Web.config files in .NET web applications.

This is not exactly a security issue, not exactly because those files are not reachable from outside the webserver, so your database user and password aren't there to be exploited by any wit user.

However, many developers (among whose I am) state that Web.config is potentially vulnerable to an internal intrusion, as anyone with access to the server filesystem would be able to retrieve that sensible info. As most of security issues at company levels came from an "enemy within" our task as security concerned developers is to, at least, difficult this task to a potential breacher.

The easiest way to do this is to encrypt connectionStrings section on Web.config files, wich is also ideal as .NET Framework will decrypt them automatically when accessing it without you having to code any complex "on the fly" decrypt method.

I used to do this using aspnet_regiis command, wich have some options to easily encrypt sections on the configuration files.

However this was far to be optimal, as on my usual work environment, where projects suffer constant variations even after going live and new builds are often uploaded to the server, I find myself forgetting usually to reencrypt Web.config after an update.

This was a pain, as I actually was concerned and prone to tight security on our developments, but it was just dependant to my memory (wich is not exactly in good shape :( ).

So I was googling for a way to automatize the process, and I was surprised about how many different options there were to programatically encrypt sections on the Web.config while none of them (at least none I've found) explained how to automatize the process to avoid publishing an update with an unencrypted Web.config.

So I decided to try something: Many tutorials and code snippets showed how to create a simple view to encrypt/decrypt sections on the code, but I wanted to execute that code each time I upload a new build, not just on user interaction. Then... why not calling a method to encrypt the sensible data on Application_OnStart?

This method (located as you surely know on Global.asax file) is executed each time your whole app restarts, and this includes each time you upload a recompiled new build.

So I take one of the multiple examples on the web that liked me more than others and simplified it at maximum to create a static class with a method to encrypt the connectionStrings section of Web.config:

using System;
                      using System.Configuration;
                      using System.Web.Configuration;
                      
                      public static class StringConnEncryption {
                          public static void Encrypt() {
                              //Encryption provider
                              string strProvider = "RSAProtectedConfigurationProvider";
                      
                              Configuration oConfiguration = null;
                              ConnectionStringsSection oSection = null;
                      
                              try {
                                  oConfiguration = WebConfigurationManager.OpenWebConfiguration("~");
                      
                                  if (oConfiguration != null) {
                                      bool bChanged = false;
                      
                                      oSection = oConfiguration.GetSection("connectionStrings") as ConnectionStringsSection;
                                          
                                      if (oSection != null) {
                                          if (!oSection.ElementInformation.IsLocked && !oSection.SectionInformation.IsLocked) {
                                              if (!oSection.SectionInformation.IsProtected) {
                                                  bChanged = true;
                                                  oSection.SectionInformation.ProtectSection(strProvider);
                                              }
                                          }
                                      }
                      
                                      if (bChanged) {
                                          oSection.SectionInformation.ForceSave = true;
                                          oConfiguration.Save();
                                      }
                                  }
                              } catch (Exception ex) {
                                  throw (ex);
                              }
                          }
                      }

Open in new window


You just need to call this method on your Application_OnStart() method:

StringConnEncryption.Encrypt();

Open in new window


You can check the original code I used for the class at this article of Dariush Tasdighi

This way your Web.config will get encrypted on the first access to the site each time you rebuild your app. You still need to access the site to fire the code, but surely after an update you check that everything it's ok, and this will be enough to fire the encrypting code.

Also, you don't need to fear that on iis restart the code fires again an re-encrypt your Web.config, as the class check if the section is already encrypted before procceeding.

Note that you can easily extend the class to encrypt other sections on Web.config and to add a decryption system (check Dariush's article).

I hope this simple idea helps you.
1
4,429 Views

Comments (2)

CERTIFIED EXPERT
Most Valuable Expert 2011
Top Expert 2015

Commented:
Wouldn't it make more sense to establish a good deployment solution that could take care of such menial tasks for you rather than having to embed such code into every web project you deploy? This would give you one point of maintenance rather than X points of maintenance.

Functionally, the approach works, but I think for an enterprise scenario it would not be fruitful.

Author

Commented:
On my case I have to deploy projects to different servers on different clients, every one with different security policies and issues, so to establish a centralized solution is not an actual option.

And actually there's no maintenance to bear with this approach. You just have some code that encrypts on upload. You have nothing to change or activate/disactivate prior to the upload, I don't see why could it be a problem in a single multi-application enterprise server.

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.