The many flavors of the .NET platform, including .NET Core and .NET Framework, store configuration data in readable XML files, i.e. web.config or app.config. Many times, sensitive data like connection strings, user credentials, and API keys are stored in these files. Storing sensitive data can be a security risk when those files are added to your source control system. Anyone with access to your source control can read those files and gain access to the sensitive information contained within.
.NET allows you to store connection strings and other sensitive data outside of the main configuration file in an associated file. This capability lets you keep sensitive data out of your source control system. For an added level of protection, the associated file can be secured using file level access permissions. Plus, changes made to values in the associated file do not require you to restart your application.
configSource provide the ability to store setting values in files associated with your configuration file. You provide the location of your associated file via these attributes. The biggest difference between the attributes is that the
file attribute merges values in the associated file with those in the configuration file, while the
configSource attribute replaces the settings in the configuration file with those from the associated file. Generally, you use the
file attribute for application settings and the configSource attribute for connection strings.
The configSource Attribute
Let's take a look at how you would move your connection strings out of a web.config file and into an associated file. A typical connectionSettings section looks like the following:
<connectionStrings> <add name="appConnection" connectionString="data source=localhost;initial catalog=<myDB>;user id=<myUser>;password=<myPwd>"/> </connectionStrings>
To move the connection strings to a separate file, create a text file named "ConnectionStrings.config" in your application's root folder. Open the file and add the connection string section. Back in the web.config file, set the
configSource attribute value to the file name created above and remove the individual connection string settings. The connectionStrings section in your web.config file should look like the following:
<connectionStrings configSource="ConnectionStrings.config"> </connectionStrings>
The configSource attribute can also be applied to the sessionState section. If you use a database to store your application's session state, you can move the connection string for your session state database to an associated file using the same technique used on the connectionStrings attribute.
Remember, the values listed in your associated file using the
configSource attribute will completely replace those in your web.config file.
The file Attribute
Next let's move sensitive application settings from the appSettings section using the
file attribute. The process is the same as described above using the configSource attribute; add the
file attribute to the appSettings section and set its value to the name of the associated file; create a file to store the application settings (use a different file name from the one used for the configSource settings); move the sensitive settings to the new file.
Since .NET will merge the values between the configuration file and the associated file, you can continue to keep non-sensitive values in the main configuration file and move only those you want to keep secret. The
file attribute doesn't force you to save the associated file in the root folder. You can optionally supply a different folder location. Here's a snippet of how your web.config file might look after making these changes:
<appSettings file="../../MyPrivateFolder/applicationSettings.config"> <add name="nonSensitiveSetting" value="not a sensitive value" /> </appSettings>
Your associated application setting file might look something like:
<appSettings> <add name="SensitiveSetting" value="sensitive value" /> </appSettings>
After moving settings to separate files you'll want to be sure and exclude the associated configuration files from your source control system. If you need additional security you can apply permissions to each file to prevent unauthorized access to the settings.
In my shop, we created separate configuration files for each environment. Grouping files by environment allows us to distribute connection strings for our development environment without exposing settings for our staging and production environments.
If you are looking for a convenient solution to separate sensitive data from your configuration files, this is it. You get the flexibility of storing configuration data outside of your source control system, and a little added security with the ability to specify permissions on your configuration files. Given the ease of implementation, I think you'll find this solution a worthwhile choice for your .NET applications.