1. Overview:
Enabling HTTP Strict Transport Security (HSTS) for Tomcat 8:
HSTS is abbreviated as HTTP Strict Transport Security. HTTP Strict Transport Security (HTTP ) is a web security policy mechanism that helps to protect websites against protocol downgrade attacks and cookie hijacking.Most of the companies do the Security vulnerability scan for your application and may be saying missing HTTP Strict Transport Security is missing as part of response. Please add HTTP header in response.
This can be done in two ways.
1) Tomcat 8 built in filter
2) Implementing Custom Filter
2. Tomcat 8 built in filter
Before doing this, You must enable HTTPS redirect protocol in server. This post designed for tomcat server.When we receive the HTTP request then internally need to redirect to HTTPS. below is the configuration for this.
2.1 tomcat8/conf/server.xml
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
2.2 Tomcat server configuration:
If your application is deployed in tomcat 8 server, then there is a built in filter that will fulfill all your needs. HttpHeaderSecurityFilter class is provided by tomcat server. We must have tomcat version 8 to enable this feature.Built in filter: org.apache.catalina.filters.HttpHeaderSecurityFilter
HSTS_HEADER_NAME = "Strict-Transport-Security"; is a predefined value and can not be changed by the developer. This constant is part of the HttpHeaderSecurityFilter.
Below are the parameters which can be configured in web.xml file.
private boolean hstsEnabled;Add the following configuration in tomcat8/conf/web.xml file which is loaded during server startup.
private int hstsMaxAgeSeconds;
private boolean hstsIncludeSubDomains;
private boolean hstsPreload;
private String hstsHeaderValue;
<filter>
<filter-name>httpHeaderSecurity</filter-name>
<filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>hstsMaxAgeSeconds</param-name>
<param-value>31536000</param-value>
</init-param>
<init-param>
<param-name>hstsIncludeSubDomains</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>hstsPreload</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>httpHeaderSecurity</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
After adding, we should be now able to see in response header.
Strict-Transport-Security: max-age=31536000; includeSubDomains
The main advantage of configuring at server level is this is applicable for the all the application that deployed in this server and no need to configure for each application.
Drawback is we must take a note that while upgrading the tomcat server, we must do this change otherwise way be open for attackers.
3. Implementing Custom Filter
We can write our own filter to add HSTS in the response for every request. In some cases 1st methodology will not work even if we are using tomcat 8+ version.Our custom filter class must implements interface javax.servlet.Filter and provide implementations for init(), doFilter() , destroy() methods.
I have written custom filter named HSTSFilter class and should be configured in web.xml file.
3.1 Custom HSTS Filter
package com.java.w3shools;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HSTSFilter implements Filter {
private static final String HEADER_NAME = "Strict-Transport-Security";
private static final String MAX_AGE_DIRECTIVE = "max-age=%s";
private static final String INCLUDE_SUB_DOMAINS_DIRECTIVE = "includeSubDomains";
private static final Logger logger = LoggerFactory.getLogger(HSTSFilter.class);
private int maxAgeSeconds = 0;
private boolean includeSubDomains = false;
private String directives;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
logger.debug("request.isSecure() :: " + request.isSecure());
System.out.println("request.isSecure() :: " + request.isSecure());
if (request.isSecure() && response instanceof HttpServletResponse) {
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader(HEADER_NAME, this.directives);
}
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
maxAgeSeconds = Integer.parseInt(filterConfig.getInitParameter("maxAgeSeconds"));
includeSubDomains = "true".equals(filterConfig.getInitParameter("includeSubDomains"));
if (this.maxAgeSeconds <= 0) {
throw new ServletException("Invalid maxAgeSeconds value :: " + maxAgeSeconds);
}
this.directives = String.format(MAX_AGE_DIRECTIVE, this.maxAgeSeconds);
if (this.includeSubDomains) {
this.directives += (" ; " + INCLUDE_SUB_DOMAINS_DIRECTIVE);
}
System.out.println("directives :: "+directives);
}
@Override
public void destroy() {
}
}
3.2 Web.xml:
<filter>
<filter-name>HSTSFilter</filter-name>
<filter-class>com.java.w3shools.HSTSFilter</filter-class>
<init-param>
<param-name>maxAgeSeconds</param-name>
<param-value>31536000</param-value>
</init-param>
<init-param>
<param-name>includeSubDomains</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>HSTSFilter</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
4. Testing
How to test HSTS is enabled or not
Implementing of HSTS is one challenging task and testing is the main part.
How to test HSTS changes are applied to the web application?
There are mainly three ways.
Result expected:
Eg. curl -s -D- http://localhost:8080/HSTSFilterDemo/index.html | grep Strict
4.2 Chrome extension Postman
4.3 Using third party website
https://tools.geekflare.com/tools/hsts-test
https://hstspreload.org/
5. Conclusion
In this tutorial, We have seen what is HSTS and how to implement using tomcat built-in filter and custom hsts filter. In further article, discussed testing whether strict-transport-security is added as part of response or not.Complete project source code showed in this article is available on GitHub.
0 Comments