HADOOP-12964. Http server vulnerable to clickjacking (haibochen via rkanter)
(cherry picked from commit 042a3ae960
)
This commit is contained in:
parent
0a94c6d9da
commit
2e2caeb50e
|
@ -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:
|
||||||
|
@ -1152,9 +1147,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 {
|
||||||
|
@ -1274,6 +1271,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1290,4 +1288,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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue