.NET Framework 2.0 Security Guidelines - Sensitive Data
From Guidance Share
- J.D. Meier, Alex Mackman, Blaine Wastell, Prashant Bansode, Chaitanya Bijwe
Use protected configuration to protect sensitive data in configuration files
Use .NET 2.0 protected configuration to protect sensitive data in configuration files. For ASP.NET Web.config files, you can use the Aspnet_regiis tool to encrypt specific sections. The sections of a Web.config file that usually contain sensitive information that you need to encrypt are the following:
- <appSettings>. This section contains custom application settings.
- <connectionStrings>. This section contains connection strings.
- <identity>. This section can contain impersonation credentials.
- <sessionState>. The section contains the connection string for the out-of-process session state provider.
Protected configuration supports DPAPI and RSA encryption. To use the DPAPI provider with the machine key store (the default configuration) to encrypt the connectionStrings section, run the following command from a command prompt:
aspnet_regiis -pe "connectionStrings" -app "/MachineDPAPI"
- -pe specifies the configuration section to encrypt.
- -app specifies your Web application's virtual path. If your application is nested, you need to specify the nested path from the root directory, for example "/test/aspnet/MachineDPAPI"
- -prov specifies the provider name.
The .NET Framework 2.0 SDK supports RSAProtectedConfigurationProvider and DPAPIProtectedConfigurationProvider protected configuration providers, which you use with the Aspnet_regiis tool.
- RSAProtectedConfigurationProvider. This is the default provider and uses the RSA public key encryption to encrypt and decrypt data. Use this provider to encrypt configuration files for use on multiple Web servers in a Web farm.
- DPAPIProtectedConfigurationProvider. This provider uses DPAPI to encrypt and decrypt data. Use this provider to encrypt configuration files for use on a single Windows Server.
For more information, see the following documents:
- "How To: Encrypt Configuration Sections in ASP.NET 2.0 Using DPAPI," at http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000005.asp.
- "How To: Encrypt Configuration Sections in ASP.NET 2.0 Using RSA" at http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000006.asp.
Minimize the exposure of secrets in memory
When manipulating secrets, consider how the secret data is stored in memory. How long is the secret data retained in clear text format? Clear text secrets held in your process address space are vulnerable if an attacker is able to probe your application's address space. Also, if the page of memory containing the secret is swapped out to the page file, the secret data is vulnerable if someone gains access to the page file. Similarly, clear text secrets held in memory appear in the crash dump file if a process crashes. To minimize the exposure of secrets in memory, consider the following measures:
- Avoid creating multiple copies of the secret. Having multiple copies of the secret data increases your attack surface. Pass references to secret data instead of making copies of the data. Also realize that if you store secrets in immutable System.String objects, after each string manipulation, a new copy is created.
- Keep the secret encrypted for as long as possible. Decrypt the data at the last possible moment before you need to use the secret.
- Clean the clear text version of the secret as soon as you can. Replace the clear text copy of the secret data with zeros as soon as you have finished with it.
Prior to .NET Framework 2.0, the use of byte arrays was recommended to help implement these guidelines. Byte arrays can be pinned in memory, encrypted, and replaced with zeros. In .NET Framework 2.0, use SecureString instead.
Where possible, use SecureString rather than System.String
Consider using the System.Security.SecureString type to help protect secrets in memory. SecureString objects use DPAPI encryption to store data in an encrypted format in memory. They are only decrypted when they are accessed. Although you have to decrypt the data to use it, by using SecureString instead of System.String you gain a number of benefits:
- You help to minimize the number of copies of the secret held in memory, which reduces the attack surface.
- You reduce the amount of time that the secret is visible to an attacker who has access either to your process memory address space or to the page file.
- You increase the likelihood that an encrypted version of the secret rather than a clear text version will end up in a dump file if your process crashes.
Note Unfortunately, in many scenarios you are forced to convert the SecureString to a System.String before you can use it. For example, few .NET Framework API methods currently provide overloads that support SecureString. Use of SecureString is less appropriate in ASP.NET applications. For example, It is unlikely you can take a credit card number from a Web page without the number at some point passing through a System.String because most of the form-related APIs do not have function overloads that permit use of SecureString instead of System.String.