IIS 7.0 Forced HTTPS Redirect: Diagnosing and Fixing Unwanted SSL Redirection in Windows Server 2008 R2


2 views

Working with IIS 7.0 on Windows Server 2008 R2, I recently encountered a puzzling behavior where direct domain access (domain.com) would forcibly redirect to https://www.domain.com, while the www-prefixed version worked normally. This occurred despite:

  • No explicit redirect rules in IIS
  • No requireSSL settings in web.config
  • Clean bindings configuration with both HTTP and HTTPS ports

After extensive troubleshooting, these are the areas worth investigating:

// Sample URL Rewrite rule that might cause this (check web.config)
<rule name="Force HTTPS" enabled="false">
    <match url="(.*)" />
    <conditions>
        <add input="{HTTPS}" pattern="^OFF$" />
    </conditions>
    <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
</rule>

Check these often-overlooked configuration sources:

  1. ApplicationHost.config: Located at %windir%\system32\inetsrv\config\
  2. WordPress plugins: Some security plugins implement forced SSL
  3. ARR (Application Request Routing): If installed

Here's how I systematically eliminated possibilities:

1. Verify bindings in IIS Manager:
   - HTTP: *:80 (hostname empty)
   - HTTPS: *:443 (hostname empty)

2. Check for URL Rewrite rules at both:
   - Site level
   - Server level

3. Examine the raw config files:
   %systemroot%\System32\inetsrv\config\applicationHost.config
   Site-specific web.config

In my case, the issue stemmed from an obscure setting in the applicationHost.config file:

<location path="Default Web Site">
    <system.webServer>
        <httpRedirect enabled="false" />
        <access sslFlags="None" /> <!-- Critical line -->
    </system.webServer>
</location>

Additionally, I had to add this to my web.config to override any inherited settings:

<configuration>
    <system.webServer>
        <httpRedirect enabled="false" />
        <rewrite>
            <rules>
                <rule name="No HTTPS Redirect" patternSyntax="Wildcard" stopProcessing="true">
                    <match url="*" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                        <add input="{HTTPS}" pattern="off" />
                    </conditions>
                    <action type="None" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

For those using newer IIS versions, consider this more elegant solution:

// In IIS Manager:
1. Open "SSL Settings" for your site
2. Uncheck "Require SSL"
3. Set "Client Certificates" to "Ignore"

// Or via command line:
appcmd.exe set config "Default Web Site" -section:system.webServer/security/access /sslFlags:"None" /commit:apphost

Working with IIS 7.0 on Windows Server 2008 R2, I recently encountered a puzzling behavior where accessing domain.com would automatically redirect to https://www.domain.com, while www.domain.com remained properly served over HTTP. This occurred despite:

  • No explicit redirect rules in IIS
  • No Require SSL settings enabled
  • No URL Rewrite rules forcing HTTPS
  • WordPress being configured with standard permalinks

First, let's verify the server's actual response using curl:

curl -v http://domain.com
* Connected to domain.com (x.x.x.x) port 80
> GET / HTTP/1.1
< HTTP/1.1 301 Moved Permanently
< Location: https://www.domain.com/

The 301 status confirms this is a permanent redirect happening at the server level.

1. IIS Site Bindings

Verify bindings in IIS Manager:

Get-WebBinding -Name "Default Web Site" | Format-Table -Property protocol,bindingInformation

Expected output should show clean HTTP bindings:

protocol bindingInformation
------- -----------------
http    *:80:www.domain.com
http    *:80:domain.com
https   *:443:

2. WordPress Configuration

Check wp_options table for suspect settings:

SELECT * FROM wp_options WHERE option_name IN ('siteurl', 'home', 'https_detection_errors');

Also inspect wp-config.php for forced SSL:

define('FORCE_SSL_ADMIN', false);
define('FORCE_SSL_LOGIN', false);

Even if not explicitly configured, some CMS platforms may set HSTS headers. Check response headers:

curl -I http://domain.com
HTTP/1.1 301 Moved Permanently
Strict-Transport-Security: max-age=31536000; includeSubDomains

To remove in IIS:

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <remove name="Strict-Transport-Security" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

Even without explicit rules, inherited configurations might exist. Check applicationHost.config:

%windir%\system32\inetsrv\appcmd list config -section:system.webServer/rewrite/rules

Sample rewrite rule to force HTTPS would look like:

<rule name="Force HTTPS" enabled="false">
    <match url="(.*)" />
    <conditions>
        <add input="{HTTPS}" pattern="off" />
    </conditions>
    <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
</rule>
  1. Clear all browser cache and HSTS settings
  2. Restart IIS (iisreset /noforce)
  3. Verify at protocol level using telnet or curl
  4. Check for network-level redirects (load balancers, CDNs)