Compatibilidad con la seguridad de transporte estricta de HTTP (HSTS) de IIS 10.0, versión 1709

por Yanbing Shi

En la versión 1709 de IIS 10.0, el administrador tiene la opción de habilitar el redireccionamiento de HSTS y HTTP a HTTPS en el nivel de sitio.

Compatibilidad

Versión Notas
IIS 10.0, versión 1709 Las características descritas en este artículo se presentaron en IIS 10.0, versión 1709.
IIS 10.0 y versiones anteriores Las características descritas en este artículo no se admiten antes la versión 1709 de IIS 10.0.

Seguridad de transporte estricta de HTTP (HSTS)

La seguridad de transporte estricta de HTTP (HSTS), con la especificación RFC 6797, permite a un sitio web declararse como un host seguro e informar a los exploradores de que solo deben ponerse en contacto mediante conexiones HTTPS. HSTS es una mejora de seguridad de participación opcional que aplica HTTPS y reduce significativamente la capacidad de ataques de tipo "Man in the middle" para interceptar solicitudes y respuestas entre servidores y clientes.

HSTS aplica el uso de HTTPS mediante una directiva que requiere compatibilidad tanto de servidores web como de exploradores. Un host web habilitado para HSTS puede incluir un encabezado de respuesta HTTP especial "Strict-Transport-Security" (STS) junto con una directiva "max-age" en una respuesta HTTPS para solicitar al explorador que use HTTPS para cualquier comunicación posterior. El explorador recibe el encabezado y memoriza la directiva HSTS durante el número de segundos especificados por la directiva "max-age". En este período, si un usuario intenta visitar el mismo sitio web, pero escribe http:// u omite por completo el esquema, el explorador convertirá automáticamente el vínculo no seguro al seguro (https://) y realiza una conexión HTTPS al servidor. Una vez que se recibe una respuesta mediante HTTPS, el explorador también impide que el usuario "haga clic en" cualquier advertencia de seguridad (por ejemplo, una advertencia sobre un certificado de servidor no válido). Para aprovechar HSTS, el explorador debe ver el encabezado HSTS al menos una vez. Para proteger al usuario en la primera conexión a un dominio determinado, HSTS tiene un mecanismo independiente para cargar previamente una lista de dominios registrados en el explorador de forma inmediata.

Desafíos al habilitar HSTS antes de IIS 10.0, versión 1709

Antes de la versión 1709 de IIS 10.0, habilitar HSTS en un servidor IIS requiere una configuración compleja.

Se proporcionan dos soluciones para habilitar HSTS antes de la versión 1709 de IIS 10.0 para un escenario de ejemplo: el administrador web quiere habilitar HSTS para un dominio contoso.com que acepte conexiones HTTP y HTTPS y redirija todo el tráfico HTTP a HTTPS. La redirección en este escenario no es segura por naturaleza, pero sigue siendo un patrón seguido por muchos sitios web que admiten HTTPS. La razón fundamental para seguir escuchando HTTP es que el sitio web no tiene control sobre cómo pueden intentar conectarse los visitantes: mediante HTTPS o simplemente mediante HTTP sin formato. La habilitación de HSTS reduce considerablemente el número de redirecciones de HTTP no seguro a HTTPS bajo la condición de que el explorador vea el encabezado STS durante la primera conexión HTTPS correcta (ya sea mediante la visita directa o mediante redireccionamiento).

Solución 1: módulo de redireccionamiento HTTP + encabezados personalizados

El redireccionamiento de todo el tráfico HTTP a HTTPS se puede lograr mediante el módulo de redireccionamiento HTTP con dos sitios web independientes, uno para HTTP y el otro para HTTPS, para evitar un bucle de redireccionamiento infinito.

<sites>
    <site name="Contoso-http" id="1" serverAutoStart="true">
        <application path="/" applicationPool="Contoso-http">
            <virtualDirectory path="/" physicalPath="C:\inetpub\Contoso-http" />
        </application>
        <bindings>
            <binding protocol="http" bindingInformation="*:80:contoso.com" />
        </bindings>
    </site>
    <site name="Contoso-https" id="2" serverAutoStart="true">
        <application path="/" applicationPool="Contoso-https">
            <virtualDirectory path="/" physicalPath="C:\inetpub\Contoso-https" />
        </application>
        <bindings>
            <binding protocol="https" bindingInformation="*:443:contoso.com" sslFlags="0" />
        </bindings>
    </site>
    <siteDefaults>
        <logFile logFormat="W3C" directory="%SystemDrive%\inetpub\logs\LogFiles" />
        <traceFailedRequestsLogging directory="%SystemDrive%\inetpub\logs\FailedReqLogFiles" />
    </siteDefaults>
    <applicationDefaults applicationPool="DefaultAppPool" />
    <virtualDirectoryDefaults allowSubDirConfig="true" />
</sites>

Una regla de redireccionamiento se configura en el archivo web.config del sitio HTTP para enrutar todo su tráfico al sitio HTTPS, el cual sirve realmente el contenido.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <httpRedirect enabled="true" destination="https://contoso.com" httpResponseStatus="Permanent" />
    </system.webServer>
</configuration>

El encabezado STS se puede agregar mediante encabezados personalizados configurando el archivo web.config del sitio HTTPS.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <add name="Strict-Transport-Security" value="max-age=31536000" />
            </customHeaders>
        </httpProtocol>
    </system.webServer>
</configuration>

Solución 2: módulo de reescritura de direcciones URL

Una solución alternativa consiste en instalar el módulo de reescritura de direcciones URL y configurar reglas de reescritura para un único sitio web con enlaces HTTP y HTTPS. El redireccionamiento de HTTP a HTTPS se puede especificar mediante una regla de entrada, mientras que agregar el encabezado STS a las respuestas HTTPS se puede lograr mediante una regla de salida.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Redirect HTTP to HTTPS" stopProcessing="true">
                    <match url="(.*)" />
                    <conditions>
                        <add input="{HTTPS}" pattern="off" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
                </rule>
            </rules>
            <outboundRules>
                <rule name="Add the STS header in HTTPS responses">
                    <match serverVariable="RESPONSE_Strict_Transport_Security" pattern=".*" />
                    <conditions>
                        <add input="{HTTPS}" pattern="on" />
                    </conditions>
                    <action type="Rewrite" value="max-age=31536000" />
                </rule>
            </outboundRules>
        </rewrite>
    </system.webServer>
</configuration>

Compatibilidad nativa con HSTS de IIS 10.0, versión 1709

Con la versión 1709 de IIS 10.0, HSTS se admite ahora de forma nativa. La configuración para habilitar HSTS se simplifica significativamente: HSTS se puede habilitar en el nivel de sitio configurando los atributos del elemento <hsts> en cada elemento <site>; puede encontrar más detalles en la referencia de configuración de HSTS Configuración de HSTS para un sitio web<>.

El escenario de ejemplo se puede lograr simplemente configurando los atributos enabled, max-age y redirectHttpToHttps del elemento <hsts> del sitio web mediante los cmdlets IISAdministration de PowerShell siguiendo el tutorial.

Import-Module IISAdministration
Reset-IISServerManager -Confirm:$false
Start-IISCommitDelay

$sitesCollection = Get-IISConfigSection -SectionPath "system.applicationHost/sites" | Get-IISConfigCollection
$siteElement = Get-IISConfigCollectionElement -ConfigCollection $sitesCollection -ConfigAttribute @{"name"="Contoso"}
$hstsElement = Get-IISConfigElement -ConfigElement $siteElement -ChildElementName "hsts"
Set-IISConfigAttributeValue -ConfigElement $hstsElement -AttributeName "enabled" -AttributeValue $true
Set-IISConfigAttributeValue -ConfigElement $hstsElement -AttributeName "max-age" -AttributeValue 31536000
Set-IISConfigAttributeValue -ConfigElement $hstsElement -AttributeName "redirectHttpToHttps" -AttributeValue $true

Stop-IISCommitDelay
Remove-Module IISAdministration

A continuación, se muestran las configuraciones de HSTS para el sitio web:

<site name="Contoso" id="1">
    <application path="/" applicationPool="Contoso">
        <virtualDirectory path="/" physicalPath="C:\Contoso\Content" />
    </application>
    <bindings>
        <binding protocol="http" bindingInformation="*:80:contoso.com" />
        <binding protocol="https" bindingInformation="*:443:contoso.com" sslFlags="0" />
    </bindings>
    <hsts enabled="true" max-age="31536000" redirectHttpToHttps="true" />
</site>

La compatibilidad nativa de HSTS también se puede usar junto con el módulo de redireccionamiento de HTTP para escenarios más complejos.

Por ejemplo, un sitio web contoso.com redirige todo el tráfico a su subdominio www.contoso.com y ambos sitios web aceptan conexiones HTTP y HTTPS. Este es un escenario típico si en el sitio web es preferible tener una sola dirección canónica. Se recomienda habilitar HSTS para el dominio raíz y el subdominio, ya que los usuarios pueden visitar directamente uno mediante HTTP o HTTPS. La habilitación del atributo includeSubDomains del elemento <hsts> del dominio raíz mejora aún más la cobertura de la directiva HSTS para todos sus subdominios.

<sites>
    <site name="Contoso" id="1">
        <application path="/" applicationPool="Contoso">
            <virtualDirectory path="/" physicalPath="C:\inetpub\Contoso" />
        </application>
        <bindings>
            <binding protocol="http" bindingInformation="*:80:contoso.com" />
            <binding protocol="https" bindingInformation="*:443:contoso.com" sslFlags="0" />
        </bindings>
        <hsts enabled="true" max-age="31536000" includeSubDomains="true" redirectHttpToHttps="true" />
    </site>
    <site name="Contoso-www" id="2">
        <application path="/" applicationPool="Contoso-www">
            <virtualDirectory path="/" physicalPath="C:\inetpub\Contoso-www" />
        </application>
        <bindings>
            <binding protocol="http" bindingInformation="*:80:www.contoso.com" />
            <binding protocol="https" bindingInformation="*:443:www.contoso.com" sslFlags="0" />
        </bindings>
        <hsts enabled="true" max-age="31536000" redirectHttpToHttps="true" />
    </site>
    <siteDefaults>
        <logFile logFormat="W3C" directory="%SystemDrive%\inetpub\logs\LogFiles" />
        <traceFailedRequestsLogging directory="%SystemDrive%\inetpub\logs\FailedReqLogFiles" />
    </siteDefaults>
    <applicationDefaults applicationPool="DefaultAppPool" />
    <virtualDirectoryDefaults allowSubDirConfig="true" />
</sites>

Además, el redireccionamiento desde el dominio raíz al subdominio se puede configurar mediante el elemento <httpRedirect> del archivo web.config del sitio del dominio raíz. Con esta configuración, una solicitud HTTP para contoso.com primero se redirigirá a HTTPS y, a continuación, la solicitud HTTPS al mismo sitio se redirigirá a www.contoso.com con el encabezado STS agregado en la respuesta.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <httpRedirect enabled="true" destination="https://www.contoso.com" httpResponseStatus="Permanent" />
    </system.webServer>
</configuration>

Las configuraciones de ejemplo anteriores también se aplican al escenario de redireccionamiento del tráfico desde un sitio de origen a un sitio de destino que no es un subdominio del sitio de origen, con una modificación menor en la configuración que consiste en deshabilitar includeSubDomains para el sitio de origen.