浏览代码

HADOOP-12964. Http server vulnerable to clickjacking (haibochen via rkanter)

(cherry picked from commit 042a3ae960883c263adc76f16d0ea3438d8b12be)
Robert Kanter 9 年之前
父节点
当前提交
d9d12b9e72

+ 23 - 6
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java

@@ -55,10 +55,7 @@ import org.apache.hadoop.conf.ConfServlet;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.CommonConfigurationKeys;
 import org.apache.hadoop.fs.CommonConfigurationKeys;
 import org.apache.hadoop.security.AuthenticationFilterInitializer;
 import org.apache.hadoop.security.AuthenticationFilterInitializer;
-import org.apache.hadoop.security.authentication.util.FileSignerSecretProvider;
-import org.apache.hadoop.security.authentication.util.RandomSignerSecretProvider;
 import org.apache.hadoop.security.authentication.util.SignerSecretProvider;
 import org.apache.hadoop.security.authentication.util.SignerSecretProvider;
-import org.apache.hadoop.security.authentication.util.ZKSignerSecretProvider;
 import org.apache.hadoop.security.ssl.SslSocketConnectorSecure;
 import org.apache.hadoop.security.ssl.SslSocketConnectorSecure;
 import org.apache.hadoop.jmx.JMXJsonServlet;
 import org.apache.hadoop.jmx.JMXJsonServlet;
 import org.apache.hadoop.log.LogLevel;
 import org.apache.hadoop.log.LogLevel;
@@ -98,8 +95,6 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Lists;
 import com.sun.jersey.spi.container.servlet.ServletContainer;
 import com.sun.jersey.spi.container.servlet.ServletContainer;
 
 
-import static org.apache.hadoop.security.authentication.server
-    .AuthenticationFilter.*;
 /**
 /**
  * Create a Jetty embedded server to answer http requests. The primary goal is
  * Create a Jetty embedded server to answer http requests. The primary goal is
  * to serve up status information for the server. There are three contexts:
  * to serve up status information for the server. There are three contexts:
@@ -1156,9 +1151,11 @@ public final class HttpServer2 implements FilterContainer {
   /**
   /**
    * A Servlet input filter that quotes all HTML active characters in the
    * A Servlet input filter that quotes all HTML active characters in the
    * parameter names and values. The goal is to quote the characters to make
    * parameter names and values. The goal is to quote the characters to make
-   * all of the servlets resistant to cross-site scripting attacks.
+   * all of the servlets resistant to cross-site scripting attacks. It also
+   * sets X-FRAME-OPTIONS in the header to mitigate clickjacking attacks.
    */
    */
   public static class QuotingInputFilter implements Filter {
   public static class QuotingInputFilter implements Filter {
+    private static final XFrameOption X_FRAME_OPTION = XFrameOption.SAMEORIGIN;
     private FilterConfig config;
     private FilterConfig config;
 
 
     public static class RequestQuoter extends HttpServletRequestWrapper {
     public static class RequestQuoter extends HttpServletRequestWrapper {
@@ -1278,6 +1275,7 @@ public final class HttpServer2 implements FilterContainer {
       } else if (mime.startsWith("application/xml")) {
       } else if (mime.startsWith("application/xml")) {
         httpResponse.setContentType("text/xml; charset=utf-8");
         httpResponse.setContentType("text/xml; charset=utf-8");
       }
       }
+      httpResponse.addHeader("X-FRAME-OPTIONS", X_FRAME_OPTION.toString());
       chain.doFilter(quoted, httpResponse);
       chain.doFilter(quoted, httpResponse);
     }
     }
 
 
@@ -1294,4 +1292,23 @@ public final class HttpServer2 implements FilterContainer {
     }
     }
 
 
   }
   }
+
+  /**
+   * The X-FRAME-OPTIONS header in HTTP response to mitigate clickjacking
+   * attack.
+   */
+  public enum XFrameOption {
+    DENY("DENY") , SAMEORIGIN ("SAMEORIGIN"), ALLOWFROM ("ALLOW-FROM");
+
+    XFrameOption(String name) {
+      this.name = name;
+    }
+
+    private final String name;
+
+    @Override
+    public String toString() {
+      return this.name;
+    }
+  }
 }
 }

+ 10 - 0
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java

@@ -235,6 +235,16 @@ public class TestHttpServer extends HttpServerFunctionalTest {
     assertEquals("text/html; charset=utf-8", conn.getContentType());
     assertEquals("text/html; charset=utf-8", conn.getContentType());
   }
   }
 
 
+  @Test
+  public void testHttpResonseContainsXFrameOptions() throws IOException {
+    URL url = new URL(baseUrl, "");
+    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+    conn.connect();
+
+    String xfoHeader = conn.getHeaderField("X-FRAME-OPTIONS");
+    assertTrue("X-FRAME-OPTIONS is absent in the header", xfoHeader != null);
+  }
+
   /**
   /**
    * Dummy filter that mimics as an authentication filter. Obtains user identity
    * Dummy filter that mimics as an authentication filter. Obtains user identity
    * from the request parameter user.name. Wraps around the request so that
    * from the request parameter user.name. Wraps around the request so that