IIS 7.0 : Securing Configuration – Securing Sensitive Configuration

The information in the configuration files in the IIS 7.0 configuration hierarchy is protected by the restricted permissions specified by the NTFS ACLs on each file. These permissions should prevent unauthorized users from being able to access these files. 

However, this alone may not provide a sufficient level of protection for especially sensitive information stored in configuration files, such as user names and passwords of custom application pool identities. It is essential to prevent this information from being discovered even if an attacker manages to compromise the local Web server and gain access to the configuration file containing the information. In addition, if someone copies the configuration file off the server for archival or transport reasons, an attacker should not be able to read the secrets stored in the configuration file. To ensure this, IIS 7.0 provides the ability to encrypt specific information stored in configuration.

Using Configuration Encryption to Store Configuration Secrets

IIS 7.0 configuration encryption works by encrypting the contents of configuration attributes for which encryption is enabled before storing their values in the configuration file. Therefore, even if someone obtains access to the file, they cannot read the contents of the attribute without decrypting it first.

Whether or not configuration encryption is used for each attribute is determined by the attribute’s definition in the schema of the containing configuration section. The schema also serves as a mechanism to select the encryption provider used to encrypt the data for this attribute .

When any configuration tool or API writes the value of each encrypted attribute, the configuration system will automatically encrypt it using the configured encryption provider before persisting it to the configuration file on disk. If you inspect the resulting configuration file, you will see the encrypted value, as shown in the following code example for the password attribute in the application pool definition inside the system.applicationHost/applicationPools configuration section.

<applicationPools>
    <add name="MyAppPool">
        <processModel identityType="SpecificUser" userName="TestUser"
password="[enc:IISWASOnlyAesProvider:N8mr4dLU6PnMW5xlmCWg6914cKePgeU0fTbxew
ZppiwyTLmBQh0mZnFywQO78pQY:enc]" />
    </add>
</applicationPools>

The configuration system decrypts the attribute automatically when it is accessed, provided that the caller of the configuration system has the rights to use the encryption provider used to perform the encryption. Therefore, the decryption and encryption process is completely transparent to the administrator, while ensuring that the resulting configuration is not stored in plain text.

Selecting Encryption Providers

IIS provides several encryption providers that can be used to encrypt configuration, in addition to several encryption providers provided by the .NET Framework. One of these providers is used for each configuration attribute that is marked for encryption. The providers are listed in Table 1.

Table 1. Configuration Encryption Providers
Provider Use Encryption Key Access
RsaProtectedConfiguration Provider Encrypting .NET Framework configuration sections using exportable RSA encryption RSA machine key: SYSTEM and administrators only; grant access using Aspnet_regiis.exe -pa.
DataProtectionConfiguration Provider Encrypting .NET Framework configuration sections using machine-local Data Protection API encryption By default, everyone on the Web server; optionally user-based key
IISWASOnlyRsaProvider Encrypting IIS configuration sections read by WAS using exportable RSA encryption RSA machine key: SYSTEM and administrators only
IISWASOnlyAesProvider Encrypting IIS configuration sections read by WAS using AES encryption Session key encrypted with RSA machine key: SYSTEM and administrators only
AesProvider Encrypting IIS configuration sections read by the IIS worker process using AES encryption Session key encrypted with RSA machine key: IIS_IUSRS, NT Service\WMSvc

.NET Framework creates both the RsaProtectedConfigurationProvider and the DataProtectionConfigurationProvider providers. These providers are primarily used to encrypt .NET configuration for ASP.NET applications using the Aspnet_regiis.exe tool.

Note

You cannot use IIS configuration encryption to encrypt .NET configuration sections. Likewise, you cannot use .NET configuration encryption to encrypt the contents of IIS configuration sections with Aspnet_regiis.exe. If you attempt to read .NET configuration sections encrypted with .NET configuration encryption by using IIS configuration APIs, you will receive an error, because IIS does not support section-level encryption used by the .NET Framework configuration system.

You can use the IIS encryption providers—IISWASOnlyRsaProvider, IISWASOnlyAesProvider, and AesProvider to encrypt IIS configuration sections.

IISWASOnlyRsaProvider and IISWASOnlyAesProvider are both used to encrypt configuration sections that WAS reads, such as the system.applicationHost/applicationPools section, and do not allow IIS worker processes to decrypt the configuration. The IISWASOnlyAesProvider provides better performance because it uses AES encryption using an RSA encrypted session key, instead of using full RSA encryption, and is used by default. The session key itself is encrypted using the RSA key container used by IISWASOnlyAesProvider, so it has the same access requirements. Configuration attributes encrypted using these providers can only be decrypted by SYSTEM and members of the Administrators group.

The AesProvider provider is an AES provider that uses a session key encrypted using an RSA key container that has permissions for the IIS_IUSRS group, therefore allowing IIS worker processes to encrypt and decrypt configuration encrypted with this provider. This is the provider used by default by all IIS configuration sections that are read by IIS worker processes. It is also the provider you should consider using to protect your custom configuration sections. Configuration attributes encrypted using this provider can be decrypted by any IIS application.

Note

The IIS configuration system does not support pluggable encryption providers unlike the .NET configuration system. However, you can configure new instances of the IIS configuration provider types to use different key containers for encryption purposes.

You can also create additional instances of the RSA and AES providers by creating new entries in the configProtectedData configuration section, and configure them to use new RSA key containers. You can create new RSA key containers by using the Aspnet_regiis.exe –pc command, as described at http://msdn2.microsoft.com/en-us/library/2w117ede.aspx.

You can then manipulate the permissions on the RSA key to determine who can use it to encrypt and decrypt configuration by using the Aspnet_regiis.exe –pa and Aspnet_regiis –pr commands.

Keep in mind the following guidelines when using encryption:

  • Configuration encrypted with IISWASOnlyAesProvider can only be decrypted by members of the Administrators group. This provider is only used to encrypt configuration read exclusively by WAS.

  • Configuration encrypted using AesProvider can be decrypted by any IIS application. It can be used to protect configuration from being disclosed outside of the Web server, but it is not a way to protect configuration from applications running on the Web server. It also does not protect configuration used by one application pool from another application pool (although this protection may be afforded by proper NTFS permissions configured for application pool isolation).

  • If you require to encrypt configuration for each application pool as an additional isolation measure, you should create separate RSA keys for each application pool identity and ACL them for that application pool using the Application Pool SIDs or custom application pool identities. Then you can create a provider for each application pool, using the corresponding RSA keys, and encrypt the configuration for each application pool using the corresponding provider.

  • In order to share a configuration on a Web farm or deploy an application with a encrypted configuration to another server, you must share encryption keys and provider definitions between the original server on which encryption was performed and the target server. When exporting encryption key containers, be sure to use a strong password and protect these keys from being accessed by unauthorized users. You can learn more about exporting encryption keys here: http://msdn2.microsoft.com/en-us/library/2w117ede.aspx.

Caution

Changing the permissions on the RSA key containers may lead to compromise of the encryption keys and therefore may expose your encrypted configuration. Do not change the default permissions on the built-in IIS RSA key containers.

Limitations of Storing Secrets in Configuration

When you store secrets in configuration, the secret is protected by both the NTFS permissions on the configuration file and configuration encryption, if configured. However, you should be aware of the following limitations that may impact the security of your secret:

  • NTFS permissions provide the basic level of protection for secrets in configuration files. However, when configuration files are archived, copied off the machine, or sent over a network, this protection is lost. Always use encryption to provide protection for secrets in these cases.

  • Any code in the IIS worker process can decrypt any encrypted configuration data that the IIS worker process has access to. By default, any IIS worker processes can decrypt any configuration data encrypted using the default IIS encryption provider (AesProvider).

  • Encryption is only as secure as the key that is used to perform the encryption. Therefore, be sure that only the users authorized to perform decryption have access to the key container used to perform the encryption and make sure that this key container is not compromised if it is exported off the machine.

Limiting Access to Configuration from Managed Code in Partial Trust Environments

When accessing IIS configuration from native code, the permissions set on the configuration files are the basis for determining whether or not access to the configuration is granted. Native modules and other code running in the IIS worker process can therefore read any of the configuration in the configuration file hierarchy that is not hidden by application pool isolation or encrypted with encryption keys that the IIS worker process does not have access to.

However, when managed code modules access configuration using the Microsoft.Web.Administration API, their ability to read some configuration sections can be further constrained through Code Access Security (CAS) policy configured for the application. This is similar to how CAS is used to prevent managed code applications from performing other actions that the hosting process may otherwise be allowed to perform, such as accessing files or opening network connections.

You can leverage this mechanism to prevent ASP.NET applications running in partial trust from being able to access information from certain configuration sections. This is done by setting the requirePermission attribute on the section declaration to true. When this is done, only ASP.NET applications and managed modules running with Full Trust can read the contents of these configuration sections.

Note

The requirePermission attribute only prevents the application from using the configuration APIs to read the configuration section when in partial trust. The application can still access the file directly, if the CAS policy and file permissions allow it. Because of this, requirePermission is only effective at preventing medium or below trust applications from reading the contents of configuration sections specified outside of the application’s directory structure, such as in applicationHost.config. The application can still open the distributed web.config files in its directory structure by using file IO APIs directly.

By default, no IIS configuration sections are declared with requirePermission set to true, so the contents of IIS configuration sections can be read by partial trust applications. So, this technique is more applicable to new configuration sections being declared.