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

Reply via email to