소스 검색

HDFS-17522. JournalNode web interfaces lack configs for X-FRAME-OPTIONS protection (#6814). Contributed by wangzhihui.

Signed-off-by: Vinayakumar B <vinayakumarb@apache.org>
Signed-off-by: He Xiaoqiao <hexiaoqiao@apache.org>
zhihui wang 11 달 전
부모
커밋
12e0ca6b24

+ 10 - 0
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/qjournal/server/JournalNodeHttpServer.java

@@ -78,6 +78,16 @@ public class JournalNodeHttpServer {
         DFSConfigKeys.DFS_JOURNALNODE_KERBEROS_INTERNAL_SPNEGO_PRINCIPAL_KEY,
         DFSConfigKeys.DFS_JOURNALNODE_KEYTAB_FILE_KEY);
 
+    final boolean xFrameEnabled = conf.getBoolean(
+        DFSConfigKeys.DFS_XFRAME_OPTION_ENABLED,
+        DFSConfigKeys.DFS_XFRAME_OPTION_ENABLED_DEFAULT);
+
+    final String xFrameOptionValue = conf.getTrimmed(
+        DFSConfigKeys.DFS_XFRAME_OPTION_VALUE,
+        DFSConfigKeys.DFS_XFRAME_OPTION_VALUE_DEFAULT);
+
+    builder.configureXFrame(xFrameEnabled).setXFrameOption(xFrameOptionValue);
+
     httpServer = builder.build();
     httpServer.setAttribute(JN_ATTRIBUTE_KEY, localJournalNode);
     httpServer.setAttribute(JspHelper.CURRENT_CONF, conf);

+ 86 - 0
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/qjournal/server/TestJournalNodeHttpServerXFrame.java

@@ -0,0 +1,86 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.hadoop.hdfs.qjournal.server;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hdfs.DFSConfigKeys;
+import org.apache.hadoop.hdfs.qjournal.MiniJournalCluster;
+import org.apache.hadoop.http.HttpServer2;
+
+/**
+ * Test that X-Frame-Options works correctly with JournalNodeHttpServer.
+ */
+public class TestJournalNodeHttpServerXFrame {
+
+  private static final int NUM_JN = 1;
+
+  private MiniJournalCluster cluster;
+
+  @Test
+  public void testJournalNodeXFrameOptionsEnabled() throws Exception {
+    boolean xFrameEnabled = true;
+    cluster = createCluster(xFrameEnabled);
+    HttpURLConnection conn = getConn(cluster);
+    String xfoHeader = conn.getHeaderField("X-FRAME-OPTIONS");
+    Assert.assertTrue("X-FRAME-OPTIONS is absent in the header", xfoHeader != null);
+    Assert.assertTrue(xfoHeader.endsWith(HttpServer2.XFrameOption.SAMEORIGIN.toString()));
+  }
+
+  @Test
+  public void testJournalNodeXFrameOptionsDisabled() throws Exception {
+    boolean xFrameEnabled = false;
+    cluster = createCluster(xFrameEnabled);
+    HttpURLConnection conn = getConn(cluster);
+    String xfoHeader = conn.getHeaderField("X-FRAME-OPTIONS");
+    System.out.println(xfoHeader);
+    Assert.assertTrue("unexpected X-FRAME-OPTION in header", xfoHeader == null);
+  }
+
+  @After
+  public void cleanup() throws IOException {
+    if (cluster != null) {
+      cluster.shutdown();
+      cluster = null;
+    }
+  }
+
+  private static MiniJournalCluster createCluster(boolean enabled) throws IOException {
+    Configuration conf = new Configuration();
+    conf.setBoolean(DFSConfigKeys.DFS_XFRAME_OPTION_ENABLED, enabled);
+    MiniJournalCluster jCluster =
+        new MiniJournalCluster.Builder(conf).format(true).numJournalNodes(NUM_JN).build();
+    jCluster.waitActive();
+    return jCluster;
+  }
+
+  private static HttpURLConnection getConn(MiniJournalCluster journalCluster) throws IOException {
+    JournalNode journalNode = journalCluster.getJournalNode(0);
+    URL newURL = new URL(journalNode.getHttpServerURI());
+    HttpURLConnection conn = (HttpURLConnection) newURL.openConnection();
+    conn.connect();
+    return conn;
+  }
+}