Set X-Frame-Options header to avoid clickjacking
Add HTTP filter which is applied to all HTTP responses. Based on gerrit.canLoadInIFrame and gerrit.xframeOption properties filter adds the X-Frame-Options HTTP response header. The X-Frame-Options HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in a <frame>, <iframe>, <embed> or <object>. Gerrit can use this to avoid click-jacking attacks, by ensuring that the content is not embedded into other sites. Bug: Issue 12926 Change-Id: If3f6a770332ade9924b3d1a20c092637c9380e0c
This commit is contained in:
@@ -18,6 +18,8 @@ import com.google.gerrit.extensions.registration.DynamicSet;
|
||||
import com.google.gerrit.server.plugins.Plugin;
|
||||
import com.google.gerrit.server.plugins.StopPluginListener;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Scopes;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.internal.UniqueAnnotations;
|
||||
import com.google.inject.servlet.ServletModule;
|
||||
@@ -32,11 +34,15 @@ import javax.servlet.ServletResponse;
|
||||
|
||||
/** Filters all HTTP requests passing through the server. */
|
||||
public abstract class AllRequestFilter implements Filter {
|
||||
public static ServletModule module() {
|
||||
public static Module module() {
|
||||
return new ServletModule() {
|
||||
@Override
|
||||
protected void configureServlets() {
|
||||
DynamicSet.setOf(binder(), AllRequestFilter.class);
|
||||
DynamicSet.bind(binder(), AllRequestFilter.class)
|
||||
.to(AllowRenderInFrameFilter.class)
|
||||
.in(Scopes.SINGLETON);
|
||||
|
||||
filter("/*").through(FilterProxy.class);
|
||||
|
||||
bind(StopPluginListener.class)
|
||||
|
||||
59
java/com/google/gerrit/httpd/AllowRenderInFrameFilter.java
Normal file
59
java/com/google/gerrit/httpd/AllowRenderInFrameFilter.java
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2020 The Android Open Source Project
|
||||
//
|
||||
// Licensed 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 com.google.gerrit.httpd;
|
||||
|
||||
import com.google.gerrit.server.config.GerritServerConfig;
|
||||
import com.google.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
|
||||
public class AllowRenderInFrameFilter extends AllRequestFilter {
|
||||
static final String X_FRAME_OPTIONS_HEADER_NAME = "X-Frame-Options";
|
||||
|
||||
public static enum XFrameOption {
|
||||
ALLOW,
|
||||
SAMEORIGIN;
|
||||
}
|
||||
|
||||
private final String xframeOptionString;
|
||||
private final boolean skipXFrameOption;
|
||||
|
||||
@Inject
|
||||
public AllowRenderInFrameFilter(@GerritServerConfig Config cfg) {
|
||||
XFrameOption xframeOption =
|
||||
cfg.getEnum("gerrit", null, "xframeOption", XFrameOption.SAMEORIGIN);
|
||||
boolean canLoadInIFrame = cfg.getBoolean("gerrit", "canLoadInIFrame", false);
|
||||
xframeOptionString = canLoadInIFrame ? xframeOption.name() : "DENY";
|
||||
|
||||
skipXFrameOption = xframeOption.equals(XFrameOption.ALLOW) && canLoadInIFrame;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
if (skipXFrameOption) {
|
||||
chain.doFilter(request, response);
|
||||
} else {
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
httpResponse.addHeader(X_FRAME_OPTIONS_HEADER_NAME, xframeOptionString);
|
||||
chain.doFilter(request, httpResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user