Author: markt
Date: Fri May  8 18:53:04 2015
New Revision: 1678426

URL: http://svn.apache.org/r1678426
Log:
Add support for the X-Frame-Options header

Modified:
    tomcat/trunk/conf/web.xml
    tomcat/trunk/java/org/apache/catalina/filters/HttpHeaderSecurityFilter.java
    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=1678426&r1=1678425&r2=1678426&view=diff
==============================================================================
--- tomcat/trunk/conf/web.xml (original)
+++ tomcat/trunk/conf/web.xml Fri May  8 18:53:04 2015
@@ -411,7 +411,18 @@
   <!--                       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?    -->
+  <!--                       [true]                                         -->
+  <!--                                                                      -->
+  <!--   antiClickJackingOption                                             -->
+  <!--                       What value should be used for the header. Must -->
+  <!--                       be one of DENY, SAMEORIGIN, ALLOW-FROM         -->
+  <!--                       (case-insensitive). [DENY]                     -->
+  <!--                                                                      -->
+  <!--   antiClickJackingUri IF ALLOW-FROM is used, what URI should be      -->
+  <!--                       allowed? []                                    -->
     <filter>
         <filter-name>httpHeaderSecurity</filter-name>
         
<filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>

Modified: 
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=1678426&r1=1678425&r2=1678426&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/filters/HttpHeaderSecurityFilter.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/filters/HttpHeaderSecurityFilter.java 
Fri May  8 18:53:04 2015
@@ -17,6 +17,8 @@
 package org.apache.catalina.filters;
 
 import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
 
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -43,6 +45,12 @@ public class HttpHeaderSecurityFilter ex
     private boolean hstsIncludeSubDomains = false;
     private String hstsHeaderValue;
 
+    // Click-jacking protection
+    private static final String ANTI_CLICK_JACKING_HEADER_NAME = 
"X-Frame-Options";
+    private boolean antiClickJackingEnabled = true;
+    private XFrameOption antiClickJackingOption = XFrameOption.DENY;
+    private URI antiClickJackingUri;
+    private String antiClickJackingHeaderValue;
 
     @Override
     public void init(FilterConfig filterConfig) throws ServletException {
@@ -55,6 +63,14 @@ public class HttpHeaderSecurityFilter ex
             hstsValue.append(";includeSubDomains");
         }
         hstsHeaderValue = hstsValue.toString();
+
+        // Anti click-jacking
+        StringBuilder cjValue = new 
StringBuilder(antiClickJackingOption.headerValue);
+        if (antiClickJackingOption == XFrameOption.ALLOW_FROM) {
+            cjValue.append(':');
+            cjValue.append(antiClickJackingUri);
+        }
+        antiClickJackingHeaderValue = cjValue.toString();
     }
 
 
@@ -71,6 +87,12 @@ public class HttpHeaderSecurityFilter ex
             ((HttpServletResponse) response).addHeader(HSTS_HEADER_NAME, 
hstsHeaderValue);
         }
 
+        // anti click-jacking
+        if (antiClickJackingEnabled && response instanceof 
HttpServletResponse) {
+            ((HttpServletResponse) response).addHeader(
+                    ANTI_CLICK_JACKING_HEADER_NAME, 
antiClickJackingHeaderValue);
+        }
+
         chain.doFilter(request, response);
     }
 
@@ -121,4 +143,71 @@ public class HttpHeaderSecurityFilter ex
     public void setHstsIncludeSubDomains(boolean hstsIncludeSubDomains) {
         this.hstsIncludeSubDomains = hstsIncludeSubDomains;
     }
+
+
+
+    public boolean isAntiClickJackingEnabled() {
+        return antiClickJackingEnabled;
+    }
+
+
+
+    public void setAntiClickJackingEnabled(boolean antiClickJackingEnabled) {
+        this.antiClickJackingEnabled = antiClickJackingEnabled;
+    }
+
+
+
+    public String getAntiClickJackingOption() {
+        return antiClickJackingOption.toString();
+    }
+
+
+
+    public void setAntiClickJackingOption(String antiClickJackingOption) {
+        for (XFrameOption option : XFrameOption.values()) {
+            if 
(option.getHeaderValue().equalsIgnoreCase(antiClickJackingOption)) {
+                this.antiClickJackingOption = option;
+                return;
+            }
+        }
+        // TODO i18n
+        throw new IllegalArgumentException();
+    }
+
+
+
+    public String getAntiClickJackingUri() {
+        return antiClickJackingUri.toString();
+    }
+
+
+
+    public void setAntiClickJackingUri(String antiClickJackingUri) {
+        URI uri;
+        try {
+            uri = new URI(antiClickJackingUri);
+        } catch (URISyntaxException e) {
+            throw new IllegalArgumentException(e);
+        }
+        this.antiClickJackingUri = uri;
+    }
+
+
+    private static enum XFrameOption {
+        DENY("DENY"),
+        SAME_ORIGIN("SAMEORIGIN"),
+        ALLOW_FROM("ALLOW-FROM");
+
+
+        private final String headerValue;
+
+        private XFrameOption(String headerValue) {
+            this.headerValue = headerValue;
+        }
+
+        public String getHeaderValue() {
+            return headerValue;
+        }
+    }
 }

Modified: tomcat/trunk/webapps/docs/config/filter.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/filter.xml?rev=1678426&r1=1678425&r2=1678426&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/filter.xml (original)
+++ tomcat/trunk/webapps/docs/config/filter.xml Fri May  8 18:53:04 2015
@@ -738,7 +738,27 @@ FINE: Request "/docs/config/manager.html
 
       <attribute name="hstsIncludeSubDomains" required="false">
         <p>Should the includeSubDomains parameter be included in the HSTS
-        header.</p>
+        header. If not specified, the default value of <code>false</code> will
+        be used.</p>
+      </attribute>
+
+      <attribute name="antiClickJackingEnabled" required="false">
+        <p>Should the anti click-jacking <code>X-Frame-Options</code> be added
+        to the response. If not specified, the default value of
+        <code>true</code> will be used.</p>
+      </attribute>
+
+      <attribute name="antiClickJackingOption" required="false">
+        <p>What value should be used for the ant click-jacking header? Must be
+        one of <code>DENY</code>, <code>SAMEORIGIN</code>,
+        <code>ALLOW-FROM </code> (case-insensitive). If not specified, the
+        default value of <code>DENY</code> will be used.</p>
+      </attribute>
+
+      <attribute name="antiClickJackingUri" required="false">
+        <p>IF ALLOW-FROM is used for <strong>antiClickJackingOption</strong>,
+        what URI should be allowed? If not specified, the default value of an
+        empty string will be used.</p>
       </attribute>
 
     </attributes>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to