Author: markt
Date: Fri May 8 12:32:11 2015
New Revision: 1678339
URL: http://svn.apache.org/r1678339
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=54618
Add the HSTS header by default as recommended by RFC 7527
Added:
tomcat/trunk/java/org/apache/catalina/filters/HttpHeaderSecurityFilter.java
(with props)
Modified:
tomcat/trunk/conf/web.xml
tomcat/trunk/java/org/apache/catalina/filters/Constants.java
tomcat/trunk/java/org/apache/catalina/filters/CorsFilter.java
tomcat/trunk/java/org/apache/catalina/filters/FilterBase.java
tomcat/trunk/java/org/apache/catalina/filters/LocalStrings.properties
tomcat/trunk/webapps/docs/config/filter.xml
Modified: tomcat/trunk/conf/web.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/conf/web.xml?rev=1678339&r1=1678338&r2=1678339&view=diff
==============================================================================
--- tomcat/trunk/conf/web.xml (original)
+++ tomcat/trunk/conf/web.xml Fri May 8 12:32:11 2015
@@ -395,6 +395,29 @@
<!-- ================== Built In Filter Definitions ===================== -->
+ <!-- A filter that sets various security related HTTP Response headers. -->
+ <!-- This filter supports the following initialization parameters -->
+ <!-- (default values are in square brackets): -->
+ <!-- -->
+ <!-- hstsEnabled Should the HTTP Strict Transport Security -->
+ <!-- (HSTS) header be added to the response? See -->
+ <!-- RFC 6797 for more information on HSTS. [true] -->
+ <!-- -->
+ <!-- hstsMaxAgeSeconds The max age value that should be used in the -->
+ <!-- HSTS header. Negative values will be treated -->
+ <!-- as zero. [0] -->
+ <!-- -->
+ <!-- hstsIncludeSubDomains -->
+ <!-- Should the includeSubDomains parameter be -->
+ <!-- included in the HSTS header. -->
+ <!-- -->
+
+ <filter>
+ <filter-name>httpHeaderSecurity</filter-name>
+
<filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
+ <async-supported>true</async-supported>
+ </filter>
+
<!-- A filter that sets character encoding that is used to decode -->
<!-- parameters in a POST request -->
<!--
@@ -483,6 +506,13 @@
<!-- ==================== Built In Filter Mappings ====================== -->
+ <!-- The mapping for the HTTP header security Filter -->
+ <filter-mapping>
+ <filter-name>httpHeaderSecurity</filter-name>
+ <url-pattern>/*</url-pattern>
+ <dispatcher>REQUEST</dispatcher>
+ </filter-mapping>
+
<!-- The mapping for the Set Character Encoding Filter -->
<!--
<filter-mapping>
Modified: tomcat/trunk/java/org/apache/catalina/filters/Constants.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/filters/Constants.java?rev=1678339&r1=1678338&r2=1678339&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/filters/Constants.java (original)
+++ tomcat/trunk/java/org/apache/catalina/filters/Constants.java Fri May 8
12:32:11 2015
@@ -25,8 +25,6 @@ package org.apache.catalina.filters;
*/
public final class Constants {
- public static final String Package = "org.apache.catalina.filters";
-
public static final String CSRF_NONCE_SESSION_ATTR_NAME =
"org.apache.catalina.filters.CSRF_NONCE";
Modified: tomcat/trunk/java/org/apache/catalina/filters/CorsFilter.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/filters/CorsFilter.java?rev=1678339&r1=1678338&r2=1678339&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/filters/CorsFilter.java (original)
+++ tomcat/trunk/java/org/apache/catalina/filters/CorsFilter.java Fri May 8
12:32:11 2015
@@ -79,9 +79,7 @@ import org.apache.tomcat.util.res.String
public final class CorsFilter implements Filter {
private static final Log log = LogFactory.getLog(CorsFilter.class);
-
- private static final StringManager sm =
- StringManager.getManager(Constants.Package);
+ private static final StringManager sm =
StringManager.getManager(CorsFilter.class);
/**
Modified: tomcat/trunk/java/org/apache/catalina/filters/FilterBase.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/filters/FilterBase.java?rev=1678339&r1=1678338&r2=1678339&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/filters/FilterBase.java (original)
+++ tomcat/trunk/java/org/apache/catalina/filters/FilterBase.java Fri May 8
12:32:11 2015
@@ -35,8 +35,7 @@ import org.apache.tomcat.util.res.String
*/
public abstract class FilterBase implements Filter {
- protected static final StringManager sm =
- StringManager.getManager(Constants.Package);
+ protected static final StringManager sm =
StringManager.getManager(FilterBase.class);
protected abstract Log getLogger();
Added:
tomcat/trunk/java/org/apache/catalina/filters/HttpHeaderSecurityFilter.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/filters/HttpHeaderSecurityFilter.java?rev=1678339&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/filters/HttpHeaderSecurityFilter.java
(added)
+++ tomcat/trunk/java/org/apache/catalina/filters/HttpHeaderSecurityFilter.java
Fri May 8 12:32:11 2015
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+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;
+
+/**
+ * Provides a single configuration point for security measures that required
the
+ * addition of one or more HTTP headers to the response.
+ */
+public class HttpHeaderSecurityFilter extends FilterBase {
+
+ private static final Log log =
LogFactory.getLog(HttpHeaderSecurityFilter.class);
+
+ // HSTS
+ private static final String HSTS_HEADER_NAME = "Strict-Transport-Security";
+ private boolean hstsEnabled = true;
+ private int hstsMaxAgeSeconds = 0;
+ private boolean hstsIncludeSubDomains = false;
+ private String hstsHeaderValue;
+
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ super.init(filterConfig);
+
+ // Build HSTS header value
+ StringBuilder hstsValue = new StringBuilder("max-age=");
+ hstsValue.append(hstsMaxAgeSeconds);
+ if (hstsIncludeSubDomains) {
+ hstsValue.append(";includeSubDomains");
+ }
+ hstsHeaderValue = hstsValue.toString();
+ }
+
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response,
+ FilterChain chain) throws IOException, ServletException {
+
+ if (response.isCommitted()) {
+ throw new
ServletException(sm.getString("httpHeaderSecurityFilter.committed"));
+ }
+
+ // HSTS
+ if (hstsEnabled && request.isSecure() && response instanceof
HttpServletResponse) {
+ ((HttpServletResponse) response).addHeader(HSTS_HEADER_NAME,
hstsHeaderValue);
+ }
+
+ chain.doFilter(request, response);
+ }
+
+
+ @Override
+ protected Log getLogger() {
+ return log;
+ }
+
+
+ @Override
+ protected boolean isConfigProblemFatal() {
+ // This filter is security related to configuration issues always
+ // trigger a failure.
+ return true;
+ }
+
+
+ public boolean isHstsEnabled() {
+ return hstsEnabled;
+ }
+
+
+ public void setHstsEnabled(boolean hstsEnabled) {
+ this.hstsEnabled = hstsEnabled;
+ }
+
+
+ public int getHstsMaxAgeSeconds() {
+ return hstsMaxAgeSeconds;
+ }
+
+
+ public void setHstsMaxAgeSeconds(int hstsMaxAgeSeconds) {
+ if (hstsMaxAgeSeconds < 0) {
+ hstsMaxAgeSeconds = 0;
+ } else {
+ this.hstsMaxAgeSeconds = hstsMaxAgeSeconds;
+ }
+ }
+
+
+ public boolean isHstsIncludeSubDomains() {
+ return hstsIncludeSubDomains;
+ }
+
+
+ public void setHstsIncludeSubDomains(boolean hstsIncludeSubDomains) {
+ this.hstsIncludeSubDomains = hstsIncludeSubDomains;
+ }
+}
Propchange:
tomcat/trunk/java/org/apache/catalina/filters/HttpHeaderSecurityFilter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
tomcat/trunk/java/org/apache/catalina/filters/HttpHeaderSecurityFilter.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: tomcat/trunk/java/org/apache/catalina/filters/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/filters/LocalStrings.properties?rev=1678339&r1=1678338&r2=1678339&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/filters/LocalStrings.properties
(original)
+++ tomcat/trunk/java/org/apache/catalina/filters/LocalStrings.properties Fri
May 8 12:32:11 2015
@@ -40,4 +40,5 @@ expiresFilter.filterInitialized=Filter i
expiresFilter.expirationHeaderAlreadyDefined=Request "{0}" with response
status "{1}" content-type "{2}", expiration header already defined
expiresFilter.skippedStatusCode=Request "{0}" with response status "{1}"
content-type "{1}", skip expiration header generation for given status
+httpHeaderSecurityFilter.committed=Unable to add HTTP headers since response
is already committed on entry to the HTTP header security Filter
remoteIpFilter.invalidLocation=Failed to modify the rewrite location [{0}] to
use scheme [{1}] and port [{2}]
\ No newline at end of file
Modified: tomcat/trunk/webapps/docs/config/filter.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/filter.xml?rev=1678339&r1=1678338&r2=1678339&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/filter.xml (original)
+++ tomcat/trunk/webapps/docs/config/filter.xml Fri May 8 12:32:11 2015
@@ -697,6 +697,56 @@ FINE: Request "/docs/config/manager.html
</section>
+<section name="HTTP Header Security Filter">
+
+ <subsection name="Introduction">
+
+ <p>There are a number of HTTP headers that can be added to the response to
+ improve the security of the connection. This filter provides a mechanism
for
+ adding those headers. Note that security related headers with more complex
+ requirements, like CORS, are implemted as separate Filters.</p>
+
+ </subsection>
+
+ <subsection name="Filter Class Name">
+
+ <p>The filter class name for the HTTP Header Security Filter is
+ <strong><code>org.apache.catalina.filters.HttpHeaderSecurityFilter</code>
+ </strong>.</p>
+
+ </subsection>
+
+ <subsection name="Initialisation parameters">
+
+ <p>The HTTP Header Security Filter supports the following initialization
+ parameters:</p>
+
+ <attributes>
+
+ <attribute name="hstsEnabled" required="false">
+ <p>Will an HTTP Strict Transport Security (HSTS) header be added to the
+ response. See <a href="http://tools.ietf.org/html/rfc6797">RFC 6797</a>
+ for further details of HSTS. If not specified, the default value of
+ <code>true</code> will be used.</p>
+ </attribute>
+
+ <attribute name="hstsMaxAgeSeconds" required="false">
+ <p>The max age value that should be used in the HSTS header. Negative
+ values will be treated as zero. If not specified, the default value of
+ <code>0</code> will be used.</p>
+ </attribute>
+
+ <attribute name="hstsIncludeSubDomains" required="false">
+ <p>Should the includeSubDomains parameter be included in the HSTS
+ header.</p>
+ </attribute>
+
+ </attributes>
+
+ </subsection>
+
+</section>
+
<section name="Remote Address Filter">
<subsection name="Introduction">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]