Configuring Strict Transport Security (HSTS) on WildFly

HSTS stands for HTTP Strict Transport Security. It is a method used by websites to declare that they should only be accessible using a secure connection (HTTPS). If a website declares an HSTS policy, the browser should reject all HTTP connections and prevent users from accepting insecure SSL certificates. In this tutorial we will learn how to configure in on WildFly Web server.

HTTP Strict Transport Security was defined as a web security standard in 2012 in RFC 6797. The main goal of creating this standard was to help prevent man-in-the-middle (MITM) attacks that use SSL stripping. SSL stripping is a technique in which a malicious user forces the browser to connect to a site over HTTP so that it can intercept packets and intercept or modify confidential information. HSTS is also a good way to protect against cookie hijacking.

In order to enable Strict Transport Security, there is a set of parameters which can be added to the Response Header, the most important one is the hstsMaxAgeSeconds:

  • hstsMaxAgeSeconds The max age value that should be used in the HSTS header. Negative values will be treated as zero.
  • hstsIncludeSubDomains: Should the includeSubDomains parameter be included in the HSTS header.
  • antiClickJackingEnabled: Should the anti click-jacking header X-Frame-Options be added to every response?
  • antiClickJackingOption: What value should be used for the header. Must be one of DENY, SAMEORIGIN, ALLOW-FROM
  • antiClickJackingUri : IF ALLOW-FROM is used, what URI should be allowed?
  • blockContentTypeSniffingEnabled : Should the header that blocks content type sniffing be added to every response?

In order to enable HSTS, we will set the hstsMaxAgeSeconds Parameter as Header in Undertow:

/subsystem=undertow/configuration=filter/response-header=hsts-header:add(header-name="Strict-Transport-Security",header-value="max-age=31536000;")
/subsystem=undertow/server=default-server/host=default-host/filter-ref=hsts-header:add

The following filter will be added in your Undertow configuration:

<subsystem xmlns="urn:jboss:domain:undertow:12.0">
    <server name="default-server">
        <host name="default-host" alias="localhost">
            <filter-ref name="hsts-header"/>
        </host>
    </server>
    <filters>
        <response-header name="hsts-header" header-name="Strict-Transport-Security" header-value="max-age=31536000;"/>
    </filters>
</subsystem>

If you request an HTTPS page, the following Response will be included in the Response:

hsts configuration wildfly jboss

Adding the HSTS Filter programmatically

Another strategy to add a Response Filter requires coding a class which extends the WebFilter Servlet and manually includes the Strict-Transport-Security Header in the Response:

package com.mastertheboss.servlet;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;


@WebFilter(
		urlPatterns = "/*",
		initParams = @WebInitParam(name = "maxAgeSeconds", value = "31536000")       
		)
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 int maxAgeSeconds = 0;
	private boolean includeSubDomains = false;
	private String directives;

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("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;

		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() {
	}
}

In addition,please note that to enable HTTP Strict Transport Security incoming request should pass through the HTTPS Port. If your requests are landing on the HTTP Port, you can redirect traffic by adding a filter as discussed in this tutorial: How to redirect HTTP to HTTPS in WildFly

Source code for this filter available here: https://github.com/fmarchioni/mastertheboss/tree/master/web/hsts

Found the article helpful? if so please follow us on Socials