September 25 2014

ASP.NET - Fix for HTTPS/SSL Insecure/Mixed Content Warning

I recently had to switch a number of websites over to HTTPS/SSL as a result of Google's announcement that they'll be giving a ranking boost to secure websites.

I'm running a Windows 2008 server with IIS 7 and .NET 4.5, and I used IIS URL Rewrite 2.0 to setup a 301 redirect for all requests from http to https, you can install IIS URL Rewrite 2.0 using the Microsoft Web Platform Installer, it's a quick install at only 6.1mb. Here's the rule that I added to the <system.webServer> section of my web.config file:

IIS URL Rewrite rule to 301 redirect HTTP to HTTPS

<rewrite>
  <rules>
    <rule name="Redirect everything to https:// on www domain" patternSyntax="Wildcard" stopProcessing="true">
      <match url="*" />
      <conditions logicalGrouping="MatchAny">
        <add input="{HTTP_HOST}" pattern="www.[DOMAIN].com" negate="true" />
        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
      </conditions>
      <action type="Redirect" url="https://www.[DOMAIN].com/{R:0}" redirectType="Permanent" />
    </rule>
  </rules>
</rewrite>


After setting up automatic redirects from http to https you may start seeing browser warnings about "insecure content" or "mixed content" and some content may be blocked and not displayed, this is because some of the external content references in your html are still using an insecure "http://" url. External content can include script references, css stylesheets, images, videos etc.

There are a couple of ways you can solve this problem:

  1. You can manually update all external content references in your html to use https (e.g. scripts, css, images, videos etc).
  2. If some/all of your html is managed by a CMS and out of your control then you may need to dynamically update external content references to use https before the html is sent to the browser
 

If you need to go with option 2 (as I did) then you can use IIS URL Rewrite 2.0 again to dynamically update all external content references in the html to use HTTPS / SSL before it's sent to the browser.

I used the below outbound rule to replace "http://" with "https://" in all script, link (css), img and video tags. The video tag isn't included in the pre-defined tags for URL Rewrite so I added it as a custom tag, you can extend the rule to include any other tags you need in the same way.

IIS URL Rewrite rule to force external content references to use HTTPS/SSL

<rewrite>

  ...

  <outboundRules>
    <rule name="Rewrite external references to use HTTPS" preCondition="IsHTML">
      <match filterByTags="Script, Link, Img, CustomTags" customTags="HTML5Tags" pattern="^http://(.*)$" />
      <action type="Rewrite" value="https://{R:1}" />
    </rule>
    <preConditions>
      <preCondition name="IsHTML">
        <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
      </preCondition>
    </preConditions>
    <customTags>
      <tags name="HTML5Tags">
        <tag name="Video" attribute="src" />
      </tags>
    </customTags>
  </outboundRules>
</rewrite>

This should work for any website running on IIS 7 or above including sites developed with ASP.NET MVC3, MVC4, MVC5 and Web Forms.


Sponsored by