HBASE-14148 Default HBase web pages to be non-framable.

* Sends X-Frame-Options header
* configured via hbase.http.filter.xframeoptions.mode
* defaults to DENY

Signed-off-by: Sean Busbey <busbey@cloudera.com>
This commit is contained in:
Gábor Lipták 2015-07-31 20:34:24 -04:00 committed by Sean Busbey
parent 32b1064c6c
commit dc9c2efcc9
3 changed files with 83 additions and 0 deletions

View File

@ -0,0 +1,55 @@
/**
* 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.hadoop.hbase.http;
import javax.servlet.Filter;
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 java.io.IOException;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)
public class ClickjackingPreventionFilter implements Filter {
private FilterConfig filterConfig;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpRes = (HttpServletResponse) res;
httpRes.addHeader("X-Frame-Options", filterConfig.getInitParameter("xframeoptions"));
chain.doFilter(req, res);
}
@Override
public void destroy() {
}
}

View File

@ -533,6 +533,10 @@ public class HttpServer implements FilterContainer {
addDefaultApps(contexts, appDir, conf); addDefaultApps(contexts, appDir, conf);
addGlobalFilter("safety", QuotingInputFilter.class.getName(), null); addGlobalFilter("safety", QuotingInputFilter.class.getName(), null);
Map<String, String> params = new HashMap<String, String>();
params.put("xframeoptions", conf.get("hbase.http.filter.xframeoptions.mode", "DENY"));
addGlobalFilter("clickjackingprevention",
ClickjackingPreventionFilter.class.getName(), params);
final FilterInitializer[] initializers = getFilterInitializers(conf); final FilterInitializer[] initializers = getFilterInitializers(conf);
if (initializers != null) { if (initializers != null) {
conf = new Configuration(conf); conf = new Configuration(conf);

View File

@ -588,6 +588,29 @@ public class TestHttpServer extends HttpServerFunctionalTest {
return server; return server;
} }
@Test
public void testXFrameHeaderSameOrigin() throws Exception {
Configuration conf = new Configuration();
conf.set("hbase.http.filter.xframeoptions.mode", "SAMEORIGIN");
HttpServer myServer = new HttpServer.Builder().setName("test")
.addEndpoint(new URI("http://localhost:0"))
.setFindPort(true).setConf(conf).build();
myServer.setAttribute(HttpServer.CONF_CONTEXT_ATTRIBUTE, conf);
myServer.addServlet("echo", "/echo", EchoServlet.class);
myServer.start();
String serverURL = "http://"
+ NetUtils.getHostPortString(myServer.getConnectorAddress(0));
URL url = new URL(new URL(serverURL), "/echo?a=b&c=d");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode());
assertEquals("SAMEORIGIN", conn.getHeaderField("X-Frame-Options"));
myServer.stop();
}
@Test @Test
public void testNoCacheHeader() throws Exception { public void testNoCacheHeader() throws Exception {
URL url = new URL(baseUrl, "/echo?a=b&c=d"); URL url = new URL(baseUrl, "/echo?a=b&c=d");
@ -598,6 +621,7 @@ public class TestHttpServer extends HttpServerFunctionalTest {
assertNotNull(conn.getHeaderField("Expires")); assertNotNull(conn.getHeaderField("Expires"));
assertNotNull(conn.getHeaderField("Date")); assertNotNull(conn.getHeaderField("Date"));
assertEquals(conn.getHeaderField("Expires"), conn.getHeaderField("Date")); assertEquals(conn.getHeaderField("Expires"), conn.getHeaderField("Date"));
assertEquals("DENY", conn.getHeaderField("X-Frame-Options"));
} }
/** /**