Enhance Your .NET HttpClient with HSTS Support
HTTP Strict Transport Security (HSTS) is a security feature that indicates a client to only connect to a website over HTTPS. Websites can set the Strict-Transport-Security
header to inform the client to always use HTTPS. ASP.NET Core can easily set the header, but there is no built-in feature to enable HSTS for an HttpClient
. In this post, I describe how to create an HttpClient
that supports HSTS, including the HSTS preload list.
The strategy is to create a custom HttpMessageHandler
that reads the Strict-Transport-Security
header from the response and automatically upgrades the request to HTTPS. The handler also uses the HSTS preload list to automatically upgrade requests to HTTPS for known domains.
Add the package Meziantou.Framework.Http.Hsts
to your project:
dotnet add package Meziantou.Framework.Http.Hsts
// Use the HstsClientHandler when creating the HttpClient
using var client = new HttpClient(new HstsClientHandler(new SocketsHttpHandler()), disposeHandler: true);
// Automatically upgrade to HTTPS as api.google.com is in the HSTS preload list
using var response = await client.GetAsync("http://mail.google.com");
_ = response.RequestMessage.RequestUri; // should be https://mail.google.com
// response contains the Strict-Transport-Security header, so the next request is upgraded to HTTPS
await client.GetStringAsync("https://www.meziantou.net/");
await client.GetStringAsync("http://www.meziantou.net/"); // will be upgraded to https
You can also add your own domains to the HSTS policies:
var policies = new HstsDomainPolicyCollection(includePreloadDomains: true);
policies.Add(
host: "example.com",
expiresAt: DateTimeOffset.UtcNow.AddYears(1),
includeSubdomains: true);
using var client = new HttpClient(new HstsClientHandler(new SocketsHttpHandler(), policies), disposeHandler: true);
#Additional resources
Do you have a question or a suggestion about this post? Contact me!