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.