From ddf8b2a2c43c3da3b3187b2e9b9ebd003ec8b441 Mon Sep 17 00:00:00 2001 From: Kevin Risden Date: Thu, 12 Apr 2018 21:08:15 -0500 Subject: [PATCH] HBASE-20406 HBase Thrift HTTP - Shouldn't handle TRACE/OPTIONS methods Signed-off-by: Josh Elser Signed-off-by: Ted Yu Signed-off-by: Sean Busbey --- .../hadoop/hbase/http/TestHttpServer.java | 13 ++++++++++-- .../hbase/thrift/ThriftServerRunner.java | 2 ++ .../hbase/thrift/TestThriftHttpServer.java | 21 +++++++++++++++---- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestHttpServer.java b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestHttpServer.java index 16350d5b42d..10553da1752 100644 --- a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestHttpServer.java +++ b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestHttpServer.java @@ -605,8 +605,6 @@ public class TestHttpServer extends HttpServerFunctionalTest { myServer.stop(); } - - @Test public void testNoCacheHeader() throws Exception { URL url = new URL(baseUrl, "/echo?a=b&c=d"); @@ -619,4 +617,15 @@ public class TestHttpServer extends HttpServerFunctionalTest { assertEquals(conn.getHeaderField("Expires"), conn.getHeaderField("Date")); assertEquals("DENY", conn.getHeaderField("X-Frame-Options")); } + + @Test + public void testHttpMethods() throws Exception { + // HTTP TRACE method should be disabled for security + // See https://www.owasp.org/index.php/Cross_Site_Tracing + URL url = new URL(baseUrl, "/echo?a=b"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("TRACE"); + conn.connect(); + assertEquals(HttpURLConnection.HTTP_FORBIDDEN, conn.getResponseCode()); + } } diff --git a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java index 16894ad97bd..5d887f909ae 100644 --- a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java +++ b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java @@ -79,6 +79,7 @@ import org.apache.hadoop.hbase.filter.Filter; import org.apache.hadoop.hbase.filter.ParseFilter; import org.apache.hadoop.hbase.filter.PrefixFilter; import org.apache.hadoop.hbase.filter.WhileMatchFilter; +import org.apache.hadoop.hbase.http.HttpServerUtil; import org.apache.hadoop.hbase.log.HBaseMarkers; import org.apache.hadoop.hbase.security.SaslUtil; import org.apache.hadoop.hbase.security.SaslUtil.QualityOfProtection; @@ -445,6 +446,7 @@ public class ThriftServerRunner implements Runnable { // Context handler ServletContextHandler ctxHandler = new ServletContextHandler(httpServer, "/", ServletContextHandler.SESSIONS); ctxHandler.addServlet(new ServletHolder(thriftHttpServlet), "/*"); + HttpServerUtil.constrainHttpMethods(ctxHandler); // set up Jetty and run the embedded server HttpConfiguration httpConfig = new HttpConfiguration(); diff --git a/hbase-thrift/src/test/java/org/apache/hadoop/hbase/thrift/TestThriftHttpServer.java b/hbase-thrift/src/test/java/org/apache/hadoop/hbase/thrift/TestThriftHttpServer.java index bd156bc4eb2..c3fecf68996 100644 --- a/hbase-thrift/src/test/java/org/apache/hadoop/hbase/thrift/TestThriftHttpServer.java +++ b/hbase-thrift/src/test/java/org/apache/hadoop/hbase/thrift/TestThriftHttpServer.java @@ -21,6 +21,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; +import java.net.HttpURLConnection; +import java.net.URL; import java.util.ArrayList; import java.util.List; import org.apache.hadoop.conf.Configuration; @@ -38,6 +40,7 @@ import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.THttpClient; import org.apache.thrift.transport.TTransportException; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Rule; @@ -171,8 +174,10 @@ public class TestThriftHttpServer { Thread.sleep(100); } + String url = "http://"+ HConstants.LOCALHOST + ":" + port; try { - talkToThriftServer(customHeaderSize); + checkHttpMethods(url); + talkToThriftServer(url, customHeaderSize); } catch (Exception ex) { clientSideException = ex; } finally { @@ -189,11 +194,19 @@ public class TestThriftHttpServer { } } + private void checkHttpMethods(String url) throws Exception { + // HTTP TRACE method should be disabled for security + // See https://www.owasp.org/index.php/Cross_Site_Tracing + HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); + conn.setRequestMethod("TRACE"); + conn.connect(); + Assert.assertEquals(HttpURLConnection.HTTP_FORBIDDEN, conn.getResponseCode()); + } + private static volatile boolean tableCreated = false; - private void talkToThriftServer(int customHeaderSize) throws Exception { - THttpClient httpClient = new THttpClient( - "http://"+ HConstants.LOCALHOST + ":" + port); + private void talkToThriftServer(String url, int customHeaderSize) throws Exception { + THttpClient httpClient = new THttpClient(url); httpClient.open(); if (customHeaderSize > 0) {