DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Keep Your Application Secrets Secret
  • Adding a Custom Domain and SSL to AWS EC2
  • GDPR Compliance With .NET: Securing Data the Right Way
  • Secure Your Frontend: Practical Tips for Developers

Trending

  • The Human Side of Logs: What Unstructured Data Is Trying to Tell You
  • The Cypress Edge: Next-Level Testing Strategies for React Developers
  • Cookies Revisited: A Networking Solution for Third-Party Cookies
  • Start Coding With Google Cloud Workstations
  1. DZone
  2. Coding
  3. Frameworks
  4. Strict Transport Security in ASP.NET MVC: Implementing RequireHstsAttribute

Strict Transport Security in ASP.NET MVC: Implementing RequireHstsAttribute

Learn how to better protect your web applications using a simple, and easy-to-use ASP.NET Core attribute, RequireHsts, which requires your browser to use HTTPS.

By 
Tomasz Pęczek user avatar
Tomasz Pęczek
·
May. 18, 17 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
14.7K Views

Join the DZone community and get the full member experience.

Join For Free

HTTPS is the core mechanism for accessing web resources in a secure way. One of the limitations of HTTPS is the fact that the user can manually provide a URL which doesn't contain the proper schema. In most cases, this will result in the application sending a redirect response which will tell the browser to re-request the resource using HTTPS. Unfortunately, this redirect creates a risk of a Man-in-the-Middle attack. Strict Transport Security is a security enhancement which allows web applications to inform browsers that they should always use HTTPS when accessing a given domain.

Strict Transport Security defines Strict-Transport-Security header with two directives: required max-age and optional includeSubDomains. From the moment the browser receives the Strict-Transport-Security header, it should consider the host as a Known HSTS Host for the number of seconds specified in the max-age directive. Being a Known HSTS Host means that the browser should always use HTTPS for communication. In the initially described scenario (user providing HTTP schema or no schema at all), the browser should cancel the initial request by itself and change the schema to HTTPS. Specifying the includeSubDomains directive means that a given rule applies also to all subdomains of the current domain.

In order to implement this behavior in an ASP.NET MVC application, we need to fulfill two requirements: issue a redirect when a request is being made with HTTP, and send the header when a request is being made with HTTPS. The first behavior is already available through RequireHttpsAttribute so we can inherit it - we just need to add the second.

public class RequireHstsAttribute : RequireHttpsAttribute
{
    private readonly uint _maxAge;

    public uint MaxAge { get { return _maxAge; } }

    public bool IncludeSubDomains { get; set; }

    public RequireHstsAttribute(uint maxAge)
        : base()
    {
        _maxAge = maxAge;
        IncludeSubDomains = false;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        if (filterContext.HttpContext.Request.IsSecureConnection)
        {
            StringBuilder headerBuilder = new StringBuilder();
            headerBuilder.AppendFormat("max-age={0}", _maxAge);

            if (IncludeSubDomains)
            {
                headerBuilder.Append("; includeSubDomains");
            }

            filterContext.HttpContext.Response.AppendHeader("Strict-Transport-Security", headerBuilder.ToString());
        }
        else
        {
            HandleNonHttpsRequest(filterContext);
        }
    }
}

We can now use this attribute, for example, by adding it to our global filters collection.

protected void Application_Start()
{
    ...
    GlobalFilters.Filters.Add(new RequireHstsAttribute(31536000) { IncludeSubDomains = true, Preload = true });
}


From this moment, our application will be "enforcing" HSTS. But the initial problem still has not been fully resolved - there is still that one redirect which can happen if the application is not accessed over HTTPS the first time. This is why HSTS Preload List has been created. This service allows for submitting domains which should be hardcoded, as Known HSTS Hosts, in the browsers - this removes the risk of that one potential redirect. The service is hosted by Google, but all major browsers vendors have stated that they will be using the submitted list of domains.

If one wants to include his/her application on the HSTS Preload List, after submitting the domain additional steps needs to be taken. The application must confirm the submission by including preload directive in the Strict-Transport-Security header and fulfill some additional criteria:

  • Be HTTPS only and serve all subdomains over HTTPS.
  • The value of max-age directive must be at least eighteen weeks.
  • The includeSubdomains directive must be present.

Some small adjustments to our attribute are needed in order to handle this additional scenario.

public class RequireHstsAttribute : RequireHttpsAttribute
{
    ...
    public bool Preload { get; set; }

    public RequireHstsAttribute(uint maxAge)
        : base()
    {
        ...
        Preload = false;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        ...

        if (filterContext.HttpContext.Request.IsSecureConnection)
        {
            if (Preload && (MaxAge < 10886400))
            {
                throw new InvalidOperationException("In order to confirm HSTS preload list subscription expiry must be at least eighteen weeks (10886400 seconds).");
            }

            if (Preload && !IncludeSubDomains)
            {
                throw new InvalidOperationException("In order to confirm HSTS preload list subscription subdomains must be included.");
            }

            ...

            if (Preload)
            {
                headerBuilder.Append("; preload");
            }

            filterContext.HttpContext.Response.AppendHeader("Strict-Transport-Security", headerBuilder.ToString());
        }
        else
        {
            HandleNonHttpsRequest(filterContext);
        }
    }
}


Now we have full HSTS support with preloading in an easy to use attribute just waiting to be used in your application. You can find cleaned up source code here.

ASP.NET MVC ASP.NET security application HTTPS

Published at DZone with permission of Tomasz Pęczek. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Keep Your Application Secrets Secret
  • Adding a Custom Domain and SSL to AWS EC2
  • GDPR Compliance With .NET: Securing Data the Right Way
  • Secure Your Frontend: Practical Tips for Developers

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: