One area that is often overlooked in application security is the protection of information in configuration files such as connection strings, application settings, etc... The configuration file for any application can often contain very sensitive information and as such needs to be protected. Luckily for us Microsoft thought about this and provided us with a simple mechanism to protect this type of information. This capability is not widely known, and the best part about this is that your application is completely unaware of the change so you do NOT need to refactor code that interoperates Configuration Files. The solution lies in two method calls ConfigurationSection.SectionInformation.ProtectSection(XmlNode) and ConfigurationSection.SectionInformation.UnprotectSection(). Since this is a native part of configuration section base classes, any custom configuration sections you create can also benefit from this capability. Here is a simple example of how to implement this, you can get the details from MSDN:
Generally speaking you would implement this either as part of your application installation or your application startup routines depending on when you want the data to be secured.
Configuration appConfig;
appConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//Get an instance of the connectionstrings
//configuration section
ConnectionStringsSection returnConfig;
returnConfig = (ConnectionStringsSection)appConfig.GetSection("connectionStrings");
if (!returnConfig.SectionInformation.IsProtected)
returnConfig.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");
//Protect the section
appConfig.Save();
Decrypted the configuration section is just as easy...
Configuration appConfig;
appConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//Get an instance of the connectionstrings
//configuration section
ConnectionStringsSection returnConfig;
returnConfig = (ConnectionStringsSection)appConfig.GetSection("connectionStrings");
//Decrypt the protected section
if (returnConfig.SectionInformation.IsProtected)
returnConfig.SectionInformation.UnprotectSection();
appConfig.Save();
Microsoft has supplied a couple out-of-the-box encryption providers, but if you want to create your own you can... Here is an example implemention of a custom provider.
using System;
using System.Configuration;
using System.Xml;
/// <summary>
/// This class facilitates the encryption and
/// decryption of configuration sections
/// </summary>
/// <remarks>For this to be used the Configuration
/// Provider must first be registered in the
/// consuming applications configuration file
/// using the element named
/// <example>configProtectedData</example>.
/// </remarks>
public sealed class MyProtectedConfigurationProvider
: ProtectedConfigurationProvider
{
/// <summary>
/// Encryptes the configuration section XML
/// </summary>
/// <param name="unecryptedNode">The configuration
/// section XML to be protected</param>
/// <returns>The encrypted form of the configuration
/// file section XML</returns>
/// <remarks>This should not be called directly.
/// This is called automatically by the
/// <code>ConfigurationSection.SectionInformation
/// .ProtectSection()</code> method</remarks>
/// <exception cref="ArgumentNullException">Thrown
/// when the supplied node is null</exception>
public override XmlNode Encrypt(XmlNode unecryptedNode)
{
if (unecryptedNode == null)
throw new ArgumentNullException("unecryptedNode");
string encryptedData = Encrypt(unecryptedNode.OuterXml);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
xmlDoc.LoadXml("<EncryptedData>" + encryptedData + "</EncryptedData>");
return xmlDoc.DocumentElement;
}
/// <summary>
/// Decryptes the configuration section XML
/// </summary>
/// <param name="encryptedNode">The configuration
/// section XML to be unprotected</param>
/// <returns>The decrypted form of the configuration
/// file section XML</returns>
/// <remarks>This should not be called directly.
/// This is called automatically by
/// the <code>ConfigurationSection.SectionInformation
/// .UnprotectSection()</code> method</remarks>
/// <exception cref="ArgumentNullException">Thrown
/// when the supplied node is null</exception>
public override XmlNode Decrypt(XmlNode encryptedNode)
{
if (encryptedNode == null)
throw new ArgumentNullException("encryptedNode");
string decryptedData = Decrypt(encryptedNode.InnerText);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
xmlDoc.LoadXml(decryptedData);
return xmlDoc.DocumentElement;
}
}
To use your custom provider you must first register it in the applications configuration file and then you can call it in a similar way
<configProtectedData>
<providers>
<clear />
<add name="MyProtectedConfigurationProvider"
type="MyProtectedConfigurationProvider, MyAssembly" />
</providers>
</configProtectedData>
Tags: security