Bug 54618 - Add filter implementing HTTP Strict Transport Security (HSTS) [PATCH]
Summary: Add filter implementing HTTP Strict Transport Security (HSTS) [PATCH]
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 8
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 8.5.x-trunk
Hardware: All All
: P2 enhancement with 17 votes (vote)
Target Milestone: ----
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-02-28 12:24 UTC by Jens Borgland
Modified: 2017-03-10 14:04 UTC (History)
4 users (show)



Attachments
The actual filter (4.50 KB, text/plain)
2013-02-28 12:24 UTC, Jens Borgland
Details
A test (4.87 KB, application/octet-stream)
2013-02-28 12:25 UTC, Jens Borgland
Details
New error message property (649 bytes, application/octet-stream)
2013-02-28 12:25 UTC, Jens Borgland
Details
Proposed implementation as unified diff (10.92 KB, patch)
2013-02-28 12:47 UTC, Jens Borgland
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jens Borgland 2013-02-28 12:24:54 UTC
Created attachment 30000 [details]
The actual filter

The specification for HTTP Strict Transport Security (HSTS) has now been published (RFC 6797). Tomcat should include a filter implementing the specification to make it easy to add to web applications.

I have attached an implementation suggestion.
Comment 1 Jens Borgland 2013-02-28 12:25:28 UTC
Created attachment 30001 [details]
A test
Comment 2 Jens Borgland 2013-02-28 12:25:57 UTC
Created attachment 30002 [details]
New error message property
Comment 3 Jens Borgland 2013-02-28 12:47:40 UTC
Created attachment 30003 [details]
Proposed implementation as unified diff
Comment 4 Mark Thomas 2013-02-28 14:37:22 UTC
HSTS has a fairly major hole: the bootstrap MITM problem. There are suggested solutions but the current pre-loaded lists contain a very small number of sites. Further, the practicalities of trying to build a reasonable pre-loaded list mean that a pre-loaded list is very unlikely to resolve the bootstrap MITM problem.

Personally, I not convinced of the usefulness of this feature at this point in time.
Comment 5 Jens Borgland 2013-02-28 15:18:28 UTC
I agree that the bootstrapping is a problem (and it's recognized in the RFC as well) but I still think that HSTS helps reduce the attack window quite drastically and therefore has significant benefits.

Tomcat is also often used for more or less internal applications within organizations where a pre-loaded list (perhaps configured using a group policy) may very well be a viable solution.
Comment 6 Christopher Schultz 2013-03-02 18:14:44 UTC
Is there a reason to implement this at the container level? Since it's a Filter, it can be installed directly into the web application. I think this protection is better done at the application level and not at the container. Perhaps your code could be put into the wiki for anyone who wants to use it.
Comment 7 Jens Borgland 2013-03-03 17:43:53 UTC
My thought was to make it easy for both developers and, more importantly, admins to enable HSTS without having to write or compile code. The actual implementation itself is quite trivial but I think that having the functionality available out of the box adds significant value (just like the CSRF Prevention and Expires filter for example).

HSTS is also done per host so using the filter for all applications in a container makes sense to me.

Another option could be to create a more general filter or similar that simply adds one or more configured headers (possibly based on some condition) - like mod_headers for Apache.
Comment 8 Steve Sether 2014-06-05 21:08:15 UTC
I think this is an important feature for Tomcat to support out of the box. 

Furthermore though, headers like this should be insanely easy to just add to all the headers of a domain hosted on a machine.  Apache solves this very easily with a single configuration line:

Header add Strict-Transport-Security "max-age=15768000"

So this is incredibly trivial to do in Apache since adding headers is very, very easy.  It's far harder to do this on Tomcat since it requires code modifications.  Why can't Tomcat have a similar feature?

IMO the solution should be broader than just this one header, and should be a simple config option that an admin can add or subtract rather than having to implement this on every web application.

I think it's vitally important that the admin should be able to control this, since the security feature it implements crosses multiple applications on a server, not just one.  That's something a good administrator can implement quickly, and would be far harder and more error prone to add at the application level.
Comment 9 Christopher Schultz 2014-06-06 14:44:21 UTC
(In reply to Steve Sether from comment #8)
> I think this is an important feature for Tomcat to support out of the box. 

Then vote for it: there are currently 5 votes from a single person for this issue. More votes = more attention.

> So this is incredibly trivial to do in Apache since adding headers is very,
> very easy.  It's far harder to do this on Tomcat since it requires code
> modifications.  Why can't Tomcat have a similar feature?

Adding a Filter (assuming it's already been written/compiled) only requires configuration, just like Apache httpd. If you don't have mod_headers, it "requires a code change" just as this does.

The Filter is attached to this issue. Feel free to download it and use it. It just hasn't made it into Tomcat's distribution yet.

> IMO the solution should be broader than just this one header, and should be
> a simple config option that an admin can add or subtract rather than having
> to implement this on every web application.

The Filter can be added to conf/web.xml and will apply to all web applications hosted by the container. I'm not sure in what order it will be applied, though. My wild guess without trying is that everything in conf/web.xml will be applied first, then all the filters defined in the application's WEB-INF/web.xml.

> I think it's vitally important that the admin should be able to control
> this, since the security feature it implements crosses multiple applications
> on a server, not just one.  That's something a good administrator can
> implement quickly, and would be far harder and more error prone to add at
> the application level.

Admins have the ability to modify conf/web.xml.
Comment 10 Christopher Schultz 2014-06-06 14:46:31 UTC
I think there is a bug in the Filter implementation provided by Jens:

The filter calls chain.doFilter() and then adds the header afterward. This isn't going to work for any request that generates output that exceeds the buffer size, or that explicitly calls getOutputStream().flush (or getWriter().flush).

Is anyone using this Filter implementation anywhere, or was it a proof-of-concept?
Comment 11 Konstantin Kolinko 2014-06-06 14:57:58 UTC
(In reply to Christopher Schultz from comment #9)
> 
> The Filter can be added to conf/web.xml and will apply to all web
> applications hosted by the container. I'm not sure in what order it will be
> applied, though. My wild guess without trying is that everything in
> conf/web.xml will be applied first, then all the filters defined in the
> application's WEB-INF/web.xml.

To clarify: the order is the opposite in Tomcat 7 onwards. The WEB-IND/web.xml filters are first, the ones in conf/web.xml are second. This is documented in Migration Guide.

http://tomcat.apache.org/migration-7.html#Processing_of_conf/web.xml_file
Comment 12 Konstantin Kolinko 2014-06-06 15:02:17 UTC
(In reply to Steve Sether from comment #8)
> 
> Furthermore though, headers like this should be insanely easy to just add to
> all the headers of a domain hosted on a machine.  Apache solves this very
> easily with a single configuration line:
> 
> Header add Strict-Transport-Security "max-age=15768000"

If it is that simple, maybe just use the well-known UrlRewriteFilter, as linked here:
http://wiki.apache.org/tomcat/AddOns#UrlRewrite

A <set type="response-header" /> rule will set a response header.
Comment 13 Jens Borgland 2014-06-07 07:31:50 UTC
The filter I wrote was intended as a suggestion, I haven't used this actual implementation anywhere. I agree that the header should be set before calling chain.doFilter() so if the filter is to be included in Tomcat (or used anywhere else) the order needs to be reversed.

Something like the UrlRewriteHeader or a filter providing somehting similar to mod_headers could of course be used as well. One benefit of having a more specific filter like the one I provided would be that it makes it easier for an administrator to avoid spelling or syntactic errors.
Comment 14 Matthew de Detrich 2014-07-24 08:17:40 UTC
I agree that this is something that should be able to be implemented without having to edit application code, particularly if it prevents the issues regarding ordering that Konstantin Kolinko mentioned
Comment 15 Mark Thomas 2015-05-08 12:33:17 UTC
I've just added an HTTP header security filter that adds the HSTS header by default for 9.0.x. I plan to expand the set of headers this filter adds/
Comment 16 Mark Thomas 2015-05-18 11:37:45 UTC
Added to 8.0.x for 8.0.23 onwards and 7.0.x for 7.0.63 onwards.
Comment 17 Ilguiz Latypov 2016-05-10 00:43:27 UTC
A web application using Spring hijacked the global filter configuration (did not add the header).
Comment 18 Ralf Hauser 2017-01-25 07:26:41 UTC
Interesting client side discussions in 
https://bugzilla.mozilla.org/show_bug.cgi?id=572803#c10
Comment 19 Ralf Hauser 2017-02-16 11:11:33 UTC
add a "preload" init-param as per https://hstspreload.org/

and https://bugzilla.mozilla.org/show_bug.cgi?id=1334764
Comment 20 Mark Thomas 2017-03-10 14:04:42 UTC
Support for preload has been added (hstsPreload init param on Filter)
Fixed in:
- trunk for 9.0.0.M19 onwards
- 8.5.x for 8.5.13 onwards
- 8.0.x for 8.0.43 onwards
- 7.0.x for 7.0.77 onwards