Spring HTTP Strict Transport
Security Guide: What It Is
and How to Enable It

stackhawk

StackHawk|October 8, 2021

Learn how to enable and customize in Spring the HTTP Strict Transport Security policy (HSTS), why it's needed and some considerations.

Introduction

As the internet is becoming increasingly accessible to people, the number of attacks trying to steal personal information is on the rise. We, as developers, need to protect our users' data, and sometimes, the protection needs to start even before they reach our web application. 

This post is about how we can protect our users when they first request our website using HTTP Strict Transport Security (HSTS). To illustrate this, we'll build a sample app with Spring Boot and Java and walk through how to configure HSTS. We'll also be using the Spring Security project. 

But first, let's learn a little more about what HSTS is and what kind of attack it prevents. 

Spring HTTP Strict Transport Security Guide: What It Is and How to Enable It - Picture 1 image

What Is HSTS, and What Does It Protect Us From?

HTTP Strict Transport Security (HSTS), as defined by the Internet Engineering Task Force (IETF)'s RFC6797, was designed to enforce that connections to a website may only occur within secure connections. This prevents browsers from just visiting the website using HTTP and then redirecting to HTTPS, as this may leave users vulnerable to man-in-the-middle attacks. But there's a question that you may be asking yourself. 

What is a man-in-the-middle (MitM) attack? 

Imagine you're in a coffee shop, and you connect to the Wi-Fi network called “BreWi-Fi." You log in to your bank account to make sure you have funds for extra chocolate drizzle. Unbeknownst to you, that network is from an attacker that is pretending to be the router inside the café. To you, the experience will be transparent, but they now can log all your activity. They can see in plain sight your user credentials, traffic, and other information you may not want to be stolen. 

Knowing what we want to protect against, let's see how HSTS and Spring Security can help us. 

How Does Spring Security and HSTS Protect Users?

Part of the Spring Project, Spring Security is the main component to handle security inside your application, including authentication and authorization. When you add Spring Security, it automatically adds a couple of security headers to the request. One of those headers is Strict-Transport-Security.

What this does is tell the browser that even if you don’t write the HTTPS protocol on the URL, the browser should enforce only using Transport Layer Security (TLS) for all its communication, instead of redirecting from the normal HTTP protocol. The reason for this is that, even if you're automatically redirected to https://, an attacker may have a small window to place any script before leaving the HTTP site. 

As a caveat, the browser will still need to make the first request in HTTP, and then it will be added to the preload list. You can skip this step by going to https://hstspreload.org/ and submitting your domain to be included in Chrome's HSTS Preload List. 

HSTS requires that your certificate comes directly from a certificate authority. You can use a service like Let’s Encrypt to generate free certificates for this tutorial. 

Getting Started

To start learning and configuring HSTS, we first need a sample Spring Boot project. The benefit of using Spring Boot over regular Spring is that you can get a lot of default configurations out of the box. Head over to https://start.spring.io/ and select Java as your language. Feel free to customize as you desire. Then, on the right-hand side, click on the button where it says “Add Dependencies” and select the following: 

  • Spring Web: This allows us to create our web application.

  • Spring Security

  • Thymeleaf: This will be our template engine.

Once you download the project, let’s first make sure the project runs. I built my demo using Gradle, but any commands needed will be provided for both Maven and Gradle. 

Here is how the build.gradle file looks:

Spring HTTP Strict Transport Security Guide: What It Is and How to Enable It - Picture 2 image

And here is the pom.xml file:

Spring HTTP Strict Transport Security Guide: What It Is and How to Enable It - Picture 3 image

Building the App

In the root folder, run one of the following commands, depending on if you selected Maven or Gradle: 

  • To run the application: mvn spring-boot:run (for Maven) or ./gradlew bootRun

  • To only build the jar: mvn clean package or ./gradlew bootJar

If you prefer to manually run the jar file, after calling the build command, you can run java -jar target/project-name.jar for Maven or java -jar build/lib/project-name.jar for Gradle.

Spring HTTP Strict Transport Security Guide: What It Is and How to Enable It - Picture 4 image

To confirm that Spring Security is being detected, you can see in your terminal a line with the text “Using generated security password:”. 

When you open your browser, you might see a login form with the text “Please sign in.” The default username is user, and the generated password is what appears in the terminal. Also, below that, you'll see the Tomcat port in which the application is running; the default port is :8080.

Spring HTTP Strict Transport Security Guide: What It Is and How to Enable It - Picture 5 image

If you don’t see the login form, don’t panic. As long as you see the “Using generated security password” line in your console, security has been configured. If you still want to see this page, in the following section, I'll show you how to display it. 

After logging in, the page will present you with a “Whitelabel Error Page." If you look closely, it will say that there was an unexpected error and give you a 404 status. This is because no controller or view has been routed to the default “/” domain. 

Spring HTTP Strict Transport Security Guide: What It Is and How to Enable It - Picture 5.5 image

Go to your src/main/resources/templates folder and create a file called home.html and write the following:

Spring HTTP Strict Transport Security Guide: What It Is and How to Enable It - Picture 6 image

After reloading your project, open your browser. You should see the “Hello from Spring” message on the page. Right-click on the page and select "Inspect." Then, depending on your browser, make your way to the network tab and select the localhost from the list. 

Exploring HSTS

Now that we have a working project, let's first check where we can see all the headers Spring Security provides us. 

Click on the Headers tab, and you'll see some of the default headers Spring Security adds. Not present is Strict-Transport-Security since it's hosted locally. You can visit https://spring.io/projects/spring-security and perform the same steps, and you will see the header. You can also try this after deploying your website and using a certificate.

Spring HTTP Strict Transport Security Guide: What It Is and How to Enable It - Picture 7 image

Then create a new config package in your main project directory where your main Spring app is located, and inside create a file named SecurityConfiguration

This class needs to extend the WebSecurityConfigurerAdapter. This class allows us to be able to extend and config the default security settings. You'll also need to add the @EnableWebSecurity and @Configuration annotations so that this class is picked up by Spring. 

Spring HTTP Strict Transport Security Guide: What It Is and How to Enable It - Picture 8 image

We need to override one of the configure methods, the one with the method signature of configure (HttpSecurity http). Here, we can chain options inside the HTTP parameter to customize the HTTP headers and requests. 

If you were not met with the login page, here is where you would configure it to appear. As an example, here is how you would configure Spring to display the form:

Spring HTTP Strict Transport Security Guide: What It Is and How to Enable It - Picture 9 image

http.authorizeRequests().anyResquest().authenticated().and().formLogin(). 

Here we're telling the system to authorize the requests, that any request done to the website must be authenticated, and to display the login form. 

Configuring HSTS

To configure HSTS, you need to extend the http.headers().httpStrictTransportSecurity(). This provides three methods for you to customize your headers: includeSubdomains(), preload(), maxAgeInSeconds()

Spring HTTP Strict Transport Security Guide: What It Is and How to Enable It - Picture 10 image

maxAgeInSeconds() accepts an int. This is where you determine how long HSTS should last in the browser's cache. If you want this preload to last six months, for example, you can set the value as 15,780,000. It's recommended that the value be greater than 10,368,000 seconds (120 days). Some examples of the age could be as follows: 

  • 0: This will instruct the browser to delete the HSTS policy

  • 42 days: 3,628,800

  • 6 months: 15,780,000

  • 1 year: 31,536,000

  • 2 years: 63,072,000

includeSubdomains() accepts a Boolean. It will tell the browser to include all subdomains (e.g., sampleA.example.com, sample.example.com). 

When referencing RCF6797, they state that the developer should consider adding includeSubDomain as long as the business requirements permit it. 

preload() takes a Boolean. Here, the directive tells the HSTS preload list that you want to be included. According to the hstspreload website, this should be opt-in and, unless sure, should not be included in the header. Since the list is dependent on the release schedule of the browser, by the time it goes into the list, there might be a need to remove a subdomain, which can take a large amount of time. The default value is false. 

Now that we know how to enable HSTS with Spring, there may be some testing cases in which you may want to disable the header.

Disable HSTS

To disable HSTS, inside your configure method, add the following:

Spring HTTP Strict Transport Security Guide: What It Is and How to Enable It - Picture 11 image

http.headers().httpStrictTransportSecurity().disable(); 

In some instances you might need to disable Spring Security without removing the package in its entirety. 

Disable Spring Security

Removing the @EnableWebSecurity annotation will not disable security for the package; it will default to the SecurityAutoConfiguration class. If you want to disable it, you can add to your application.properties file the following: 

Spring HTTP Strict Transport Security Guide: What It Is and How to Enable It - Picture 12 image
Spring HTTP Strict Transport Security Guide: What It Is and How to Enable It - Picture 13 image

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration 

Or you can also disable it by excluding the package in your main app:

Spring HTTP Strict Transport Security Guide: What It Is and How to Enable It - Picture 14 image

@SpringBootApplication(exclude= {SecurityAutoConfiguration.class})

Add Automated Security Testing to Your Pipeline for Free

Conclusion

Out of the box, Spring Security automatically protects against some of the more common security vulnerabilities. MitM attacks will become more common as people expect free Wi-Fi spots when they're out and about. The HTTP Strict Transport Security (HSTS) minimizes the risk of exposing user information, and it being added by default is one less thing you need to worry about as a developer. 

This post was written by Kenneth Reyes. Kenneth is a Full stack developer that has worked in different industries and with clients of all levels. He specializes in Java/Spring, Vue, and DevOps. He strives to make programming interesting for people outside the field.


StackHawk  |  October 8, 2021