Enable HTTP Strict Transport Security (HSTS) in Azure WebRoles
Solution 1
The accepted answer is confusing and the correct answer (on ServerFault) is hidden in the comments, so I'll just recap it quickly here. Basically this is what you want to do:
- Redirect all HTTP requests to HTTPS
- Add the
Strict-Transport-Security
header to all HTTPS requests
The appropriate web.config would look like this:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}"
redirectType="Permanent" />
</rule>
</rules>
<outboundRules>
<rule name="Add Strict-Transport-Security when HTTPS" enabled="true">
<match serverVariable="RESPONSE_Strict_Transport_Security"
pattern=".*" />
<conditions>
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
</conditions>
<action type="Rewrite" value="max-age=31536000" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
If you want to comply with HSTS preload you'll need includeSubDomains
and preload
in the Strict_Transport_Security
header too. Here's my full rewrite configuration, including apex redirection (I'm a yes-www guy) and easy local development setup (no HTTPS on localhost):
<rewrite>
<rules>
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{SERVER_NAME}" pattern="^localhost$" negate="true" />
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
<rule name="Redirect to www" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^yourdomain\.com" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://www.yourdomain.com/{R:1}"
redirectType="Permanent" />
</rule>
</rules>
<outboundRules>
<rule name="HSTS" enabled="true">
<match serverVariable="RESPONSE_Strict_Transport_Security" pattern=".*" />
<conditions>
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
</conditions>
<action type="Rewrite" value="max-age=31536000; includeSubDomains; preload" />
</rule>
</outboundRules>
</rewrite>
Of course, switch yourdomain
with your actual domain.
Solution 2
There is an IIS module which enables HSTS compliant with the HSTS Draft Specification (RFC 6797); you can found it here https://hstsiis.codeplex.com/
DON'T TRY THIS:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains"/>
</customHeaders>
</httpProtocol>
</system.webServer>
because this will include the STS header in HTTP responses over non-secure transport.
Related videos on Youtube
Mahmoud Samy
I'm a dad, software engineer, maker & DIYer. I has been writing code since the 90s. Developing in everything from object oriented to functional, and working on projects from web-scale to embedded devices.
Updated on September 16, 2022Comments
-
Mahmoud Samy over 1 year
How can I turn on HTTP Strict Transport Security (HSTS) for Azure WebRoles?
-
trailmax about 10 yearsSo you are after a redirecting filter that sends 301 for non secure requests? If you include these details, perhaps it would be easier to get an answer, rather than point people to RFC
-
deniz almost 9 yearsRelated: serverfault.com/questions/417173/…
-
-
PussInBoots almost 9 yearsThen, how DO you install it? Can I install the HSTS-IIS-Module-2.0.0.msi file in Azure? Or do I copy the .dlls to my bin folder for my ASP.NET MVC 5 application?
-
nmit026 about 7 yearsConsider adding
includeSubDomains
owasp.org/index.php/HTTP_Strict_Transport_Security_Cheat_Sheet -
Ohad Schneider about 7 years@et I'm already using it... look at the full rewrite configuration at the bottom.
-
Yort about 7 yearsIs there a way to make this return 308 instead of 301? I have API clients sending POST requests and sending a 301 causes them to use a GET to the alternate address instead of a POST (which doesn't work since I never see the original POST to process). My understanding is 308 implies 'keep verb' AND permanent redirect (as opposed to temporary), but I can't see how to do that with the url rewrite.
-
Ohad Schneider about 7 years@Yort looks like you're out of luck:
redirectType
– Specifies the status code to use during redirect: 301 – Permanent, 302 – Found, 303 – See other, 307 – Temporary (iis.net/learn/extensions/url-rewrite-module/…). -
Yort about 7 yearsThat's what I feared. Thanks for confirming. I may need to resort to a custom asp.net filter in my app I guess. Shame, I liked this solution.
-
Augusto Barreto about 7 yearsGreat solution. I'm using it on an Azure App Service and it works fine.
-
Jake almost 7 yearsThanks for this answer. If we want to use this for a site on a subdomain (e.g.
shop.mysite.com
) do I simply remove theRedirect to www
rule? -
Ohad Schneider almost 7 years@Jake not necessarily, that rules would only redirect anything that starts with
mysite.com
towww.mysite.com
. Hence,shop.mysite.com
(or any other subdomain) would not be affected. -
David Hamilton almost 7 years@OhadSchneider This is pretty much what I have implemented, but am having an issue with the fact I don't know the domain and that I need to make sure I don't redirect subdomains to the www version. I've tried to explain on this question: stackoverflow.com/questions/44910233/… Any chance you can advise?
-
Polyfun over 5 yearsThis solution requires an IIS extension: the URL Rewrite Module docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/….