DevOps Cloud (ADM)
Cybersecurity
IT Operations Management
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:
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;
}
}