Alexander Wels has uploaded a new change for review. Change subject: engine: Add header to each response. ......................................................................
engine: Add header to each response. - This patch adds headers to each response with the option of defining extra headers in the web.xml. There are 3 headers added by default. - X-FRAME-OPTIONS: SAMEORIGIN (To stop click jacking) - X-CONTENT-TYPE-OPTIONS: NOSNIFF (To stop mime type attacks) - X-XSS-PROTECTION: 1; MODE=BLOCK (To enable IE XSS filter) Change-Id: I4e9c26dddd0d0300d6b3d078ae763b78600f25d1 Signed-off-by: Alexander Wels <[email protected]> --- M backend/manager/modules/docs/src/main/webapp/WEB-INF/web.xml M backend/manager/modules/root/src/main/webapp/WEB-INF/web.xml A backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/servlet/HeaderFilter.java A backend/manager/modules/utils/src/test/java/org/ovirt/engine/core/utils/servlet/HeaderFilterTest.java M backend/manager/modules/welcome/src/main/webapp/WEB-INF/web.xml M frontend/webadmin/modules/frontend/src/main/resources/META-INF/web-fragment.xml M frontend/webadmin/modules/userportal-gwtp/src/main/webapp/WEB-INF/web.xml M frontend/webadmin/modules/webadmin/src/main/webapp/WEB-INF/web.xml 8 files changed, 201 insertions(+), 0 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/37/25937/1 diff --git a/backend/manager/modules/docs/src/main/webapp/WEB-INF/web.xml b/backend/manager/modules/docs/src/main/webapp/WEB-INF/web.xml index 2a5baeb..0dbc6f0 100644 --- a/backend/manager/modules/docs/src/main/webapp/WEB-INF/web.xml +++ b/backend/manager/modules/docs/src/main/webapp/WEB-INF/web.xml @@ -82,6 +82,17 @@ <filter-class>org.ovirt.engine.core.branding.BrandingFilter</filter-class> </filter> + <!-- Header filter to automatically add some headers to each response --> + <filter> + <filter-name>HeaderFilter</filter-name> + <filter-class>org.ovirt.engine.core.utils.servlet.HeaderFilter</filter-class> + </filter> + + <filter-mapping> + <filter-name>HeaderFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + <filter-mapping> <filter-name>LocaleFilter</filter-name> <url-pattern>/*</url-pattern> diff --git a/backend/manager/modules/root/src/main/webapp/WEB-INF/web.xml b/backend/manager/modules/root/src/main/webapp/WEB-INF/web.xml index 57bcb96..92d4f5b 100644 --- a/backend/manager/modules/root/src/main/webapp/WEB-INF/web.xml +++ b/backend/manager/modules/root/src/main/webapp/WEB-INF/web.xml @@ -6,6 +6,17 @@ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> + <!-- Header filter to automatically add some headers to each response --> + <filter> + <filter-name>HeaderFilter</filter-name> + <filter-class>org.ovirt.engine.core.utils.servlet.HeaderFilter</filter-class> + </filter> + + <filter-mapping> + <filter-name>HeaderFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + <!-- File servlet instance to serve the CA certificate: --> <servlet> <servlet-name>PKIResourceServlet.ca</servlet-name> diff --git a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/servlet/HeaderFilter.java b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/servlet/HeaderFilter.java new file mode 100644 index 0000000..785e7c5 --- /dev/null +++ b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/servlet/HeaderFilter.java @@ -0,0 +1,65 @@ +package org.ovirt.engine.core.utils.servlet; + +import java.io.IOException; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +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; + +public class HeaderFilter implements Filter { + + private static final String X_FRAME_OPTIONS = "X-FRAME-OPTIONS"; //$NON-NLS-1$ + // This has to be SAMEORIGIN otherwise GWT won't work. + private static final String X_FRAME_OPTIONS_DEFAULT = "SAMEORIGIN"; //$NON-NLS-1$ + + private static final String X_CONTENT_TYPE_OPTIONS = "X-CONTENT-TYPE-OPTIONS"; //$NON-NLS-1$ + private static final String X_CONTENT_TYPE_OPTIONS_DEFAULT = "NOSNIFF"; //$NON-NLS-1$ + + private static final String X_XSS_PROTECTION = "X-XSS-PROTECTION"; //$NON-NLS-1$ + private static final String X_XSS_PROTECTION_DEFAULT = "1; MODE=BLOCK"; //$NON-NLS-1$ + + private final Map<String, String> headerValueMap = new HashMap<String, String>(); + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, + ServletException { + HttpServletResponse res = (HttpServletResponse)response; + for (Map.Entry<String, String> entry: headerValueMap.entrySet()) { + res.addHeader(entry.getKey(), entry.getValue()); + } + chain.doFilter(request, response); + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + Enumeration<String> headerNames = filterConfig.getInitParameterNames(); + addDefaultsToMap(); + while(headerNames.hasMoreElements()) { + String name = headerNames.nextElement(); + //This allows for overriding the defaults. + headerValueMap.put(name.toUpperCase(), filterConfig.getInitParameter(name)); + } + } + + /** + * These are headers each response should have. + */ + private void addDefaultsToMap() { + headerValueMap.put(X_FRAME_OPTIONS, X_FRAME_OPTIONS_DEFAULT); + headerValueMap.put(X_CONTENT_TYPE_OPTIONS, X_CONTENT_TYPE_OPTIONS_DEFAULT); + headerValueMap.put(X_XSS_PROTECTION, X_XSS_PROTECTION_DEFAULT); + } + + @Override + public void destroy() { + // Do nothing. + } + +} diff --git a/backend/manager/modules/utils/src/test/java/org/ovirt/engine/core/utils/servlet/HeaderFilterTest.java b/backend/manager/modules/utils/src/test/java/org/ovirt/engine/core/utils/servlet/HeaderFilterTest.java new file mode 100644 index 0000000..8abb839 --- /dev/null +++ b/backend/manager/modules/utils/src/test/java/org/ovirt/engine/core/utils/servlet/HeaderFilterTest.java @@ -0,0 +1,88 @@ +package org.ovirt.engine.core.utils.servlet; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class HeaderFilterTest { + @Mock + HttpServletRequest mockRequest; + @Mock + HttpServletResponse mockResponse; + @Mock + FilterChain mockChain; + @Mock + FilterConfig mockConfig; + + HeaderFilter testFilter; + + @Before + public void setUp() throws Exception { + when(mockConfig.getInitParameterNames()).thenReturn(Collections.enumeration(new ArrayList<String>())); + testFilter = new HeaderFilter(); + } + + @Test + public void testFilter() throws Exception { + testFilter.init(mockConfig); + testFilter.doFilter(mockRequest, mockResponse, mockChain); + verify(mockResponse).addHeader("X-FRAME-OPTIONS", "SAMEORIGIN"); + verify(mockResponse).addHeader("X-CONTENT-TYPE-OPTIONS", "NOSNIFF"); + verify(mockResponse).addHeader("X-XSS-PROTECTION", "1; MODE=BLOCK"); + } + + @Test + public void testFilterOverride() throws Exception { + List<String> initParams = new ArrayList<String>(); + initParams.add("X-FRAME-OPTIONS"); + when(mockConfig.getInitParameter("X-FRAME-OPTIONS")).thenReturn("DENY"); + when(mockConfig.getInitParameterNames()).thenReturn(Collections.enumeration(initParams)); + testFilter.init(mockConfig); + testFilter.doFilter(mockRequest, mockResponse, mockChain); + verify(mockResponse).addHeader("X-FRAME-OPTIONS", "DENY"); + verify(mockResponse).addHeader("X-CONTENT-TYPE-OPTIONS", "NOSNIFF"); + verify(mockResponse).addHeader("X-XSS-PROTECTION", "1; MODE=BLOCK"); + } + + @Test + public void testFilterOverrideDifferentCase() throws Exception { + List<String> initParams = new ArrayList<String>(); + initParams.add("X-FRAME-options"); + when(mockConfig.getInitParameter("X-FRAME-options")).thenReturn("DENY"); + when(mockConfig.getInitParameterNames()).thenReturn(Collections.enumeration(initParams)); + testFilter.init(mockConfig); + testFilter.doFilter(mockRequest, mockResponse, mockChain); + verify(mockResponse).addHeader("X-FRAME-OPTIONS", "DENY"); + verify(mockResponse).addHeader("X-CONTENT-TYPE-OPTIONS", "NOSNIFF"); + verify(mockResponse).addHeader("X-XSS-PROTECTION", "1; MODE=BLOCK"); + } + + @Test + public void testFilterAddNew() throws Exception { + List<String> initParams = new ArrayList<String>(); + initParams.add("X-FRAME-TEST"); + when(mockConfig.getInitParameter("X-FRAME-TEST")).thenReturn("TEST"); + when(mockConfig.getInitParameterNames()).thenReturn(Collections.enumeration(initParams)); + testFilter.init(mockConfig); + testFilter.doFilter(mockRequest, mockResponse, mockChain); + verify(mockResponse).addHeader("X-FRAME-OPTIONS", "SAMEORIGIN"); + verify(mockResponse).addHeader("X-CONTENT-TYPE-OPTIONS", "NOSNIFF"); + verify(mockResponse).addHeader("X-XSS-PROTECTION", "1; MODE=BLOCK"); + verify(mockResponse).addHeader("X-FRAME-TEST", "TEST"); + } +} diff --git a/backend/manager/modules/welcome/src/main/webapp/WEB-INF/web.xml b/backend/manager/modules/welcome/src/main/webapp/WEB-INF/web.xml index 3d375dd..e8590fb 100644 --- a/backend/manager/modules/welcome/src/main/webapp/WEB-INF/web.xml +++ b/backend/manager/modules/welcome/src/main/webapp/WEB-INF/web.xml @@ -73,6 +73,17 @@ <filter-class>org.ovirt.engine.core.branding.BrandingFilter</filter-class> </filter> + <!-- Header filter to automatically add some headers to each response --> + <filter> + <filter-name>HeaderFilter</filter-name> + <filter-class>org.ovirt.engine.core.utils.servlet.HeaderFilter</filter-class> + </filter> + + <filter-mapping> + <filter-name>HeaderFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + <filter-mapping> <filter-name>LocaleFilter</filter-name> <url-pattern>/*</url-pattern> diff --git a/frontend/webadmin/modules/frontend/src/main/resources/META-INF/web-fragment.xml b/frontend/webadmin/modules/frontend/src/main/resources/META-INF/web-fragment.xml index 86dabbd7..1a13102 100644 --- a/frontend/webadmin/modules/frontend/src/main/resources/META-INF/web-fragment.xml +++ b/frontend/webadmin/modules/frontend/src/main/resources/META-INF/web-fragment.xml @@ -51,6 +51,11 @@ <filter-class>org.ovirt.engine.core.branding.BrandingFilter</filter-class> </filter> + <filter> + <filter-name>HeaderFilter</filter-name> + <filter-class>org.ovirt.engine.core.utils.servlet.HeaderFilter</filter-class> + </filter> + <servlet> <servlet-name>UserPortalHostPageServlet</servlet-name> <servlet-class>org.ovirt.engine.ui.frontend.server.gwt.UserPortalHostPageServlet</servlet-class> diff --git a/frontend/webadmin/modules/userportal-gwtp/src/main/webapp/WEB-INF/web.xml b/frontend/webadmin/modules/userportal-gwtp/src/main/webapp/WEB-INF/web.xml index 8abdb78..82a1013 100644 --- a/frontend/webadmin/modules/userportal-gwtp/src/main/webapp/WEB-INF/web.xml +++ b/frontend/webadmin/modules/userportal-gwtp/src/main/webapp/WEB-INF/web.xml @@ -59,6 +59,11 @@ <url-pattern>/*</url-pattern> </filter-mapping> + <filter-mapping> + <filter-name>HeaderFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + <servlet-mapping> <servlet-name>UserPortalHostPageServlet</servlet-name> <url-pattern>/UserPortal.html</url-pattern> diff --git a/frontend/webadmin/modules/webadmin/src/main/webapp/WEB-INF/web.xml b/frontend/webadmin/modules/webadmin/src/main/webapp/WEB-INF/web.xml index 90e8b93..b637adf 100644 --- a/frontend/webadmin/modules/webadmin/src/main/webapp/WEB-INF/web.xml +++ b/frontend/webadmin/modules/webadmin/src/main/webapp/WEB-INF/web.xml @@ -60,6 +60,11 @@ <url-pattern>/*</url-pattern> </filter-mapping> + <filter-mapping> + <filter-name>HeaderFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + <servlet-mapping> <servlet-name>WebAdminHostPageServlet</servlet-name> <url-pattern>/WebAdmin.html</url-pattern> -- To view, visit http://gerrit.ovirt.org/25937 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4e9c26dddd0d0300d6b3d078ae763b78600f25d1 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Alexander Wels <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
