Enabling HTTP Strict Transport Security (HSTS) for Tomcat 8

0 Likes

How to add HTTP Strict Transport Security (HSTS) to Tomcat 8

For Regular HSTS within Tomcat 8

Edit the web.xml file in a text editor.

Uncomment the httpHeaderSecurity filter definition and the <filter-mapping> section, and then add the hstsMaxAgeSeconds parameter, as shown below.

<filter>
<filter-name>httpHeaderSecurity</filter-name>
<filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
<init-param>
<param-name>hstsEnabled</param-name>
<param-value>true</param-value>
</init-param>
<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>
<async-supported>true</async-supported>
</filter>

<filter-mapping>
<filter-name>httpHeaderSecurity</filter-name>
<url-pattern>/*</url-pattern>
<url-pattern>*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>


If you are going to add preload (Site is on the Internet and not internal only)

If a site sends the preload directive in an HSTS header, it is considered to be requesting inclusion in the preload list and may be submitted via the form on this site.

In order to be accepted to the HSTS preload list through this form, your site must satisfy the following set of requirements:

    1. Serve a valid certificate.

 

    1. Redirect from HTTP to HTTPS on the same host, if you are listening on port 80.

 

    1. Serve all subdomains over HTTPS.

        • In particular, you must support HTTPS for the www subdomain if a DNS record for that subdomain exists.


 

    1. Serve an HSTS header on the base domain for HTTPS requests:

        • The max-age must be at least eighteen weeks (10886400 seconds).

        • The includeSubDomains directive must be specified.

        • The preload directive must be specified.

        • If you are serving an additional redirect from your HTTPS site, that redirect must still have the HSTS header (rather than the page it redirects to).




Please go to https://hstspreload.org/ to include your site and then add the following after the last init-param and before the async statement in the above statement add the following:

 <init-param>
<param-name>preload</param-name>
<param-value>true</param-value>
</init-param>


For Jira add this to the filter section of the Web.xml to enable HSTS.

<filter>
<filter-name>HstsFilter</filter-name>
<filter-class>org.apache.catalina.filters.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>

package org.apache.catalina.filters;

import java.io.IOException;

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.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;

public class HstsFilter extends FilterBase {
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 Log log = LogFactory.getLog(HstsFilter.class);

// The default is "0" like recommended in section 11.2 of RFC 6797
private int maxAgeSeconds = 0;
private boolean includeSubDomains = false;

private String directives;

public void setMaxAgeSeconds(int maxAgeSeconds) {
this.maxAgeSeconds = maxAgeSeconds;
}

public void setIncludeSubDomains(boolean includeSubDomains) {
this.includeSubDomains = includeSubDomains;
}

@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);

// Note that the HSTS header must not be included in HTTP responses
// conveyed over non-secure transport
if (request.isSecure() && response instanceof HttpServletResponse) {
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader(HEADER_NAME, this.directives);
}
}

@SuppressWarnings("boxing")
@Override
public void init(FilterConfig filterConfig) throws ServletException {
super.init(filterConfig);
if (this.maxAgeSeconds < 0) {
throw new ServletException(sm.getString(
"hsts.invalidParameterValue", this.maxAgeSeconds,
"maxAgeSeconds"));
}
this.directives = String.format(MAX_AGE_DIRECTIVE, this.maxAgeSeconds);
if (this.includeSubDomains) {
this.directives = (" ; " INCLUDE_SUB_DOMAINS_DIRECTIVE);
}
}

@Override
protected Log getLogger() {
return log;
}
}

Labels:

How To-Best Practice
Comment List
  • in reply to lhaeger
    Hi lhaeger,

    Sorry for not adding it earlier. Thought since it has been out since 2009, figured most tech folks would know that it is HTTP Strict Transport Security. Updated the article to include HSTS for Tomcat 8 and use of Jira as well for your reference. I have added preload for internet based sites as well.
    What did you search for that landed you on this page?

    Have a great day,
    Kevin
  • Would it have been too much to write out the acronym used at least once so reader can decide if this is interesting at all without googling HSTS first?
Related
Recommended